Browse Source

Merge branch 'dev' into webhooks

pull/843/head
Christopher F GitHub 7 years ago
parent
commit
e468569fa8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 936 additions and 112 deletions
  1. +2
    -2
      Discord.Net.targets
  2. +2
    -2
      README.md
  3. +1
    -1
      appveyor.yml
  4. +1
    -1
      docs/guides/getting_started/intro.md
  5. +4
    -3
      docs/guides/getting_started/samples/intro/structure.cs
  6. +1
    -1
      docs/guides/getting_started/samples/project.csproj
  7. +4
    -5
      docs/guides/voice/samples/audio_create_ffmpeg.cs
  8. +7
    -5
      docs/guides/voice/samples/audio_ffmpeg.cs
  9. +1
    -1
      docs/guides/voice/samples/joining_audio.cs
  10. +1
    -1
      src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
  11. +2
    -2
      src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
  12. +3
    -5
      src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
  13. +1
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
  14. +1
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs
  15. +1
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
  16. +3
    -5
      src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
  17. +3
    -3
      src/Discord.Net.Commands/CommandParser.cs
  18. +10
    -7
      src/Discord.Net.Commands/Info/CommandInfo.cs
  19. +3
    -3
      src/Discord.Net.Commands/Info/ParameterInfo.cs
  20. +1
    -1
      src/Discord.Net.Commands/Readers/ChannelTypeReader.cs
  21. +1
    -1
      src/Discord.Net.Commands/Readers/EnumTypeReader.cs
  22. +1
    -1
      src/Discord.Net.Commands/Readers/MessageTypeReader.cs
  23. +2
    -2
      src/Discord.Net.Commands/Readers/NullableTypeReader.cs
  24. +1
    -1
      src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs
  25. +1
    -1
      src/Discord.Net.Commands/Readers/RoleTypeReader.cs
  26. +1
    -1
      src/Discord.Net.Commands/Readers/TypeReader.cs
  27. +1
    -1
      src/Discord.Net.Commands/Readers/UserTypeReader.cs
  28. +1
    -1
      src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
  29. +10
    -0
      src/Discord.Net.Core/Entities/Emotes/EmoteProperties.cs
  30. +9
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  31. +1
    -1
      src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
  32. +24
    -19
      src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
  33. +1
    -1
      src/Discord.Net.Core/Utils/Optional.cs
  34. +2
    -1
      src/Discord.Net.Core/Utils/Preconditions.cs
  35. +16
    -0
      src/Discord.Net.Rest/API/Rest/CreateGuildEmoteParams.cs
  36. +14
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildEmoteParams.cs
  37. +44
    -0
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  38. +2
    -2
      src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
  39. +5
    -5
      src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
  40. +41
    -0
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  41. +10
    -0
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  42. +35
    -0
      src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs
  43. +1
    -1
      src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
  44. +3
    -3
      src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
  45. +10
    -0
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  46. +19
    -19
      src/Discord.Net/Discord.Net.nuspec
  47. +324
    -0
      test/Discord.Net.Tests/Tests.ChannelPermissions.cs
  48. +304
    -0
      test/Discord.Net.Tests/Tests.GuildPermissions.cs

+ 2
- 2
Discord.Net.targets View File

@@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionPrefix>2.0.0-alpha</VersionPrefix>
<VersionSuffix></VersionSuffix>
<VersionPrefix>2.0.0</VersionPrefix>
<VersionSuffix>beta</VersionSuffix>
<Authors>RogueException</Authors>
<PackageTags>discord;discordapp</PackageTags>
<PackageProjectUrl>https://github.com/RogueException/Discord.Net</PackageProjectUrl>


+ 2
- 2
README.md View File

@@ -2,11 +2,11 @@
[![NuGet](https://img.shields.io/nuget/vpre/Discord.Net.svg?maxAge=2592000?style=plastic)](https://www.nuget.org/packages/Discord.Net)
[![MyGet](https://img.shields.io/myget/discord-net/vpre/Discord.Net.svg)](https://www.myget.org/feed/Packages/discord-net)
[![Build status](https://ci.appveyor.com/api/projects/status/5sb7n8a09w9clute/branch/dev?svg=true)](https://ci.appveyor.com/project/RogueException/discord-net/branch/dev)
[![Discord](https://discordapp.com/api/guilds/81384788765712384/widget.png)](https://discord.gg/0SBTUU1wZTVjAMPx)
[![Discord](https://discordapp.com/api/guilds/81384788765712384/widget.png)](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)


+ 1
- 1
appveyor.yml View File

@@ -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 }



+ 1
- 1
docs/guides/getting_started/intro.md View File

@@ -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.


+ 4
- 3
docs/guides/getting_started/samples/intro/structure.cs View File

@@ -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


+ 1
- 1
docs/guides/getting_started/samples/project.csproj View File

@@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Discord.Net" Version="1.0.0-rc-00617" />
<PackageReference Include="Discord.Net" Version="1.*" />
</ItemGroup>

</Project>

+ 4
- 5
docs/guides/voice/samples/audio_create_ffmpeg.cs View File

@@ -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);
}
});
}

+ 7
- 5
docs/guides/voice/samples/audio_ffmpeg.cs View File

@@ -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(); }
}
}

+ 1
- 1
docs/guides/voice/samples/joining_audio.cs View File

@@ -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();
}
}

+ 1
- 1
src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs View File

@@ -7,6 +7,6 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
public abstract class ParameterPreconditionAttribute : Attribute
{
public abstract Task<PreconditionResult> CheckPermissions(ICommandContext context, ParameterInfo parameter, object value, IServiceProvider services);
public abstract Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, ParameterInfo parameter, object value, IServiceProvider services);
}
}

+ 2
- 2
src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs View File

@@ -8,11 +8,11 @@ namespace Discord.Commands
{
/// <summary>
/// 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 <see cref="Group"/> = <see cref="null"/>
/// of the preconditions to pass in order to be successful (A || B). Specifying <see cref="Group"/> = <see langword="null"/>
/// or not at all will require *all* preconditions to pass, just like normal (A &amp;&amp; B).
/// </summary>
public string Group { get; set; } = null;

public abstract Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services);
public abstract Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services);
}
}

+ 3
- 5
src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs View File

@@ -41,7 +41,7 @@ namespace Discord.Commands
GuildPermission = null;
}

public override async Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
public override async Task<PreconditionResult> 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}");


+ 1
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs View File

@@ -38,7 +38,7 @@ namespace Discord.Commands
Contexts = contexts;
}

public override Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
bool isValid = false;



+ 1
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs View File

@@ -9,7 +9,7 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireNsfwAttribute : PreconditionAttribute
{
public override Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
if (context.Channel is ITextChannel text && text.IsNsfw)
return Task.FromResult(PreconditionResult.FromSuccess());


+ 1
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs View File

@@ -12,7 +12,7 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireOwnerAttribute : PreconditionAttribute
{
public override async Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
public override async Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
switch (context.Client.TokenType)
{


+ 3
- 5
src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs View File

@@ -42,7 +42,7 @@ namespace Discord.Commands
GuildPermission = null;
}
public override Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services)
public override Task<PreconditionResult> 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}"));


+ 3
- 3
src/Discord.Net.Commands/CommandParser.cs View File

@@ -14,7 +14,7 @@ namespace Discord.Commands
QuotedParameter
}
public static async Task<ParseResult> ParseArgs(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos)
public static async Task<ParseResult> 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);


+ 10
- 7
src/Discord.Net.Commands/Info/CommandInfo.cs View File

@@ -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<PreconditionResult>();
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<IResult> 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<IResult> ExecuteAsyncInternal(ICommandContext context, object[] args, IServiceProvider services)
private async Task<IResult> 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)


+ 3
- 3
src/Discord.Net.Commands/Info/ParameterInfo.cs View File

@@ -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<TypeReaderResult> Parse(ICommandContext context, string input, IServiceProvider services = null)
public async Task<TypeReaderResult> 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;


+ 1
- 1
src/Discord.Net.Commands/Readers/ChannelTypeReader.cs View File

@@ -9,7 +9,7 @@ namespace Discord.Commands
internal class ChannelTypeReader<T> : TypeReader
where T : class, IChannel
{
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
if (context.Guild != null)
{


+ 1
- 1
src/Discord.Net.Commands/Readers/EnumTypeReader.cs View File

@@ -44,7 +44,7 @@ namespace Discord.Commands
_enumsByValue = byValueBuilder.ToImmutable();
}

public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
object enumValue;



+ 1
- 1
src/Discord.Net.Commands/Readers/MessageTypeReader.cs View File

@@ -7,7 +7,7 @@ namespace Discord.Commands
internal class MessageTypeReader<T> : TypeReader
where T : class, IMessage
{
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
ulong id;



+ 2
- 2
src/Discord.Net.Commands/Readers/NullableTypeReader.cs View File

@@ -24,11 +24,11 @@ namespace Discord.Commands
_baseTypeReader = baseTypeReader;
}

public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> 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);
}
}
}

+ 1
- 1
src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs View File

@@ -30,7 +30,7 @@ namespace Discord.Commands
_score = score;
}

public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
if (_tryParse(input, out T value))
return Task.FromResult(TypeReaderResult.FromSuccess(new TypeReaderValue(value, _score)));


+ 1
- 1
src/Discord.Net.Commands/Readers/RoleTypeReader.cs View File

@@ -9,7 +9,7 @@ namespace Discord.Commands
internal class RoleTypeReader<T> : TypeReader
where T : class, IRole
{
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
ulong id;



+ 1
- 1
src/Discord.Net.Commands/Readers/TypeReader.cs View File

@@ -5,6 +5,6 @@ namespace Discord.Commands
{
public abstract class TypeReader
{
public abstract Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services);
public abstract Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services);
}
}

+ 1
- 1
src/Discord.Net.Commands/Readers/UserTypeReader.cs View File

@@ -10,7 +10,7 @@ namespace Discord.Commands
internal class UserTypeReader<T> : TypeReader
where T : class, IUser
{
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
var results = new Dictionary<ulong, TypeReaderValue>();
IReadOnlyCollection<IUser> channelUsers = (await context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten().ConfigureAwait(false)).ToArray(); //TODO: must be a better way?


+ 1
- 1
src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs View File

@@ -20,7 +20,7 @@ namespace Discord
/// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param>
/// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param>
/// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param>
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null);
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null);
/// <summary> Returns a collection of all invites to this channel. </summary>
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null);


+ 10
- 0
src/Discord.Net.Core/Entities/Emotes/EmoteProperties.cs View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace Discord
{
public class EmoteProperties
{
public Optional<string> Name { get; set; }
public Optional<IEnumerable<IRole>> Roles { get; set; }
}
}

+ 9
- 0
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -122,5 +122,14 @@ namespace Discord
Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null);
/// <summary> Gets a collection of all webhooks for this guild. </summary>
Task<IReadOnlyCollection<IWebhook>> GetWebhooksAsync(RequestOptions options = null);
/// <summary> Gets a specific emote from this guild. </summary>
Task<GuildEmote> GetEmoteAsync(ulong id, RequestOptions options = null);
/// <summary> Creates a new emote in this guild. </summary>
Task<GuildEmote> CreateEmoteAsync(string name, Image image, Optional<IEnumerable<IRole>> roles = default(Optional<IEnumerable<IRole>>), RequestOptions options = null);
/// <summary> Modifies an existing emote in this guild. </summary>
Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null);
/// <summary> Deletes an existing emote from this guild. </summary>
Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null);
}
}

+ 1
- 1
src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs View File

@@ -10,7 +10,7 @@ namespace Discord
/// <summary> Gets a blank ChannelPermissions that grants no permissions. </summary>
public static readonly ChannelPermissions None = new ChannelPermissions();
/// <summary> Gets a ChannelPermissions that grants all permissions for text channels. </summary>
public static readonly ChannelPermissions Text = new ChannelPermissions(0b00100_0000000_1111111110001_010001);
public static readonly ChannelPermissions Text = new ChannelPermissions(0b01100_0000000_1111111110001_010001);
/// <summary> Gets a ChannelPermissions that grants all permissions for voice channels. </summary>
public static readonly ChannelPermissions Voice = new ChannelPermissions(0b00100_1111110_0000000000000_010001);
/// <summary> Gets a ChannelPermissions that grants all permissions for direct message channels. </summary>


+ 24
- 19
src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs View File

@@ -11,7 +11,7 @@ namespace Discord
/// <summary> Gets a GuildPermissions that grants all guild permissions for webhook users. </summary>
public static readonly GuildPermissions Webhook = new GuildPermissions(0b00000_0000000_0001101100000_000000);
/// <summary> Gets a GuildPermissions that grants all guild permissions. </summary>
public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_0111111110011_111111);
public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_1111111110011_111111);

/// <summary> Gets a packed value representing all the permissions in this GuildPermissions. </summary>
public ulong RawValue { get; }
@@ -28,7 +28,7 @@ namespace Discord
public bool ManageChannels => Permissions.GetValue(RawValue, GuildPermission.ManageChannels);
/// <summary> If True, a user may adjust guild properties. </summary>
public bool ManageGuild => Permissions.GetValue(RawValue, GuildPermission.ManageGuild);
/// <summary> If true, a user may add reactions. </summary>
public bool AddReactions => Permissions.GetValue(RawValue, GuildPermission.AddReactions);
/// <summary> If true, a user may view the audit log. </summary>
@@ -80,13 +80,13 @@ namespace Discord
/// <summary> Creates a new GuildPermissions with the provided packed value. </summary>
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
}

/// <summary> Creates a new GuildPermissions with the provided permissions. </summary>
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)
{ }

/// <summary> Creates a new GuildPermissions from this one, changing the provided non-null permissions. </summary>
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);



+ 1
- 1
src/Discord.Net.Core/Utils/Optional.cs View File

@@ -10,7 +10,7 @@ namespace Discord
public static Optional<T> Unspecified => default(Optional<T>);
private readonly T _value;

/// <summary> Gets the value for this paramter. </summary>
/// <summary> Gets the value for this parameter. </summary>
public T Value
{
get


+ 2
- 1
src/Discord.Net.Core/Utils/Preconditions.cs View File

@@ -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.");
}
}


+ 16
- 0
src/Discord.Net.Rest/API/Rest/CreateGuildEmoteParams.cs View File

@@ -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<ulong[]> RoleIds { get; set; }
}
}

+ 14
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildEmoteParams.cs View File

@@ -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<string> Name { get; set; }
[JsonProperty("roles")]
public Optional<ulong[]> RoleIds { get; set; }
}
}

+ 44
- 0
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -1066,6 +1066,50 @@ namespace Discord.API
return await SendJsonAsync<IReadOnlyCollection<Role>>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false);
}

//Guild emoji
public async Task<Emoji> 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<Emoji>("GET", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options);
}

public async Task<Emoji> 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<Emoji>("POST", () => $"guilds/{guildId}/emojis", args, ids, options: options);
}

public async Task<Emoji> 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<Emoji>("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<User> GetUserAsync(ulong userId, RequestOptions options = null)
{


+ 2
- 2
src/Discord.Net.Rest/Entities/Channels/RestChannel.cs View File

@@ -48,8 +48,8 @@ namespace Discord.Rest
string IChannel.Name => null;

Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(null); //Overriden
=> Task.FromResult<IUser>(null); //Overridden
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overriden
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden
}
}

+ 5
- 5
src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs View File

@@ -119,7 +119,7 @@ namespace Discord.Rest

public async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
public async Task<RestInviteMetadata> CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
public async Task<RestInviteMetadata> 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<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); //Overriden //Overriden in Text/Voice
=> AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); //Overridden //Overridden in Text/Voice
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(null); //Overriden in Text/Voice
=> Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice

//IChannel
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overriden in Text/Voice
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(null); //Overriden in Text/Voice
=> Task.FromResult<IUser>(null); //Overridden in Text/Voice
}
}

+ 41
- 0
src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs View File

@@ -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<GuildEmote> 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<GuildEmote> CreateEmoteAsync(IGuild guild, BaseDiscordClient client, string name, Image image, Optional<IEnumerable<IRole>> 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<GuildEmote> ModifyEmoteAsync(IGuild guild, BaseDiscordClient client, ulong id, Action<EmoteProperties> 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);
}
}

+ 10
- 0
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -266,6 +266,16 @@ namespace Discord.Rest
public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})";

//Emotes
public Task<GuildEmote> GetEmoteAsync(ulong id, RequestOptions options = null)
=> GuildHelper.GetEmoteAsync(this, Discord, id, options);
public Task<GuildEmote> CreateEmoteAsync(string name, Image image, Optional<IEnumerable<IRole>> roles = default(Optional<IEnumerable<IRole>>), RequestOptions options = null)
=> GuildHelper.CreateEmoteAsync(this, Discord, name, image, roles, options);
public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> 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;


+ 35
- 0
src/Discord.Net.Rest/Extensions/EmbedBuilderExtensions.cs View File

@@ -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;
}
}
}

+ 1
- 1
src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs View File

@@ -51,7 +51,7 @@ namespace Discord.Rpc

public async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
public async Task<RestInviteMetadata> CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
public async Task<RestInviteMetadata> 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;


+ 3
- 3
src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs View File

@@ -113,7 +113,7 @@ namespace Discord.WebSocket

public async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);
public async Task<RestInviteMetadata> CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
public async Task<RestInviteMetadata> 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<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); //Overriden in Text/Voice
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(GetUser(id)); //Overriden in Text/Voice
=> Task.FromResult<IUser>(GetUser(id)); //Overridden in Text/Voice
}
}

+ 10
- 0
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -439,6 +439,16 @@ namespace Discord.WebSocket
public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> GuildHelper.GetWebhooksAsync(this, Discord, options);

//Emotes
public Task<GuildEmote> GetEmoteAsync(ulong id, RequestOptions options = null)
=> GuildHelper.GetEmoteAsync(this, Discord, id, options);
public Task<GuildEmote> CreateEmoteAsync(string name, Image image, Optional<IEnumerable<IRole>> roles = default(Optional<IEnumerable<IRole>>), RequestOptions options = null)
=> GuildHelper.CreateEmoteAsync(this, Discord, name, image, roles, options);
public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> 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<SocketVoiceState> AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model)
{


+ 19
- 19
src/Discord.Net/Discord.Net.nuspec View File

@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Discord.Net</id>
<version>2.0.0-alpha$suffix$</version>
<version>2.0.0-beta$suffix$</version>
<title>Discord.Net</title>
<authors>Discord.Net Contributors</authors>
<owners>RogueException</owners>
@@ -13,28 +13,28 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<group targetFramework="net45">
<dependency id="Discord.Net.Core" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Core" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-beta$suffix$" />
</group>
<group targetFramework="netstandard1.1">
<dependency id="Discord.Net.Core" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Core" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-beta$suffix$" />
</group>
<group targetFramework="netstandard1.3">
<dependency id="Discord.Net.Core" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-alpha$suffix$" />
<dependency id="Discord.Net.Core" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rest" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Rpc" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Commands" version="2.0.0-beta$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.0.0-beta$suffix$" />
</group>
</dependencies>
</metadata>


+ 324
- 0
test/Discord.Net.Tests/Tests.ChannelPermissions.cs View File

@@ -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<ArgumentException>(() => ChannelPermissions.All(someChannel));
}
}
}

+ 304
- 0
test/Discord.Net.Tests/Tests.GuildPermissions.cs View File

@@ -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);

}

}
}

Loading…
Cancel
Save