Browse Source

Merge pull request #1 from RogueException/dev

Pulled from origin
pull/1095/head
ComputerMaster1st GitHub 7 years ago
parent
commit
75c5f4fd91
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 228 additions and 110 deletions
  1. +1
    -6
      README.md
  2. +1
    -1
      src/Discord.Net.Commands/Builders/ModuleBuilder.cs
  3. +13
    -11
      src/Discord.Net.Commands/Builders/ParameterBuilder.cs
  4. +12
    -2
      src/Discord.Net.Commands/CommandService.cs
  5. +2
    -2
      src/Discord.Net.Commands/Extensions/MessageExtensions.cs
  6. +4
    -1
      src/Discord.Net.Commands/Results/ParseResult.cs
  7. +4
    -1
      src/Discord.Net.Commands/Results/PreconditionGroupResult.cs
  8. +4
    -1
      src/Discord.Net.Commands/Results/PreconditionResult.cs
  9. +4
    -1
      src/Discord.Net.Commands/Results/SearchResult.cs
  10. +2
    -0
      src/Discord.Net.Commands/Results/TypeReaderResult.cs
  11. +2
    -2
      src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
  12. +0
    -0
      src/Discord.Net.Core/Entities/Channels/ChannelType.cs
  13. +10
    -1
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  14. +3
    -3
      src/Discord.Net.Core/Entities/Invites/IInvite.cs
  15. +4
    -4
      src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs
  16. +2
    -1
      src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs
  17. +9
    -2
      src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
  18. +1
    -0
      src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs
  19. +9
    -2
      src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
  20. +11
    -0
      src/Discord.Net.Core/Extensions/MessageExtensions.cs
  21. +1
    -1
      src/Discord.Net.Core/IDiscordClient.cs
  22. +1
    -1
      src/Discord.Net.Rest/API/Common/Invite.cs
  23. +2
    -2
      src/Discord.Net.Rest/API/Common/InviteChannel.cs
  24. +5
    -5
      src/Discord.Net.Rest/API/Common/InviteMetadata.cs
  25. +0
    -7
      src/Discord.Net.Rest/API/Rest/GetInviteParams.cs
  26. +1
    -1
      src/Discord.Net.Rest/BaseDiscordClient.cs
  27. +2
    -6
      src/Discord.Net.Rest/ClientHelper.cs
  28. +10
    -4
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  29. +4
    -4
      src/Discord.Net.Rest/DiscordRestClient.cs
  30. +18
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs
  31. +23
    -9
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs
  32. +4
    -1
      src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
  33. +6
    -0
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  34. +13
    -1
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  35. +8
    -10
      src/Discord.Net.Rest/Entities/Invites/RestInvite.cs
  36. +8
    -8
      src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs
  37. +4
    -4
      src/Discord.Net.WebSocket/BaseSocketClient.cs
  38. +2
    -2
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  39. +5
    -2
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  40. +13
    -1
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 1
- 6
README.md View File

@@ -16,13 +16,9 @@ Our stable builds available from NuGet through the Discord.Net metapackage:
The individual components may also be installed from NuGet:
- [Discord.Net.Commands](https://www.nuget.org/packages/Discord.Net.Commands/)
- [Discord.Net.Rest](https://www.nuget.org/packages/Discord.Net.Rest/)
- [Discord.Net.Rpc](https://www.nuget.org/packages/Discord.Net.Rpc/)
- [Discord.Net.WebSocket](https://www.nuget.org/packages/Discord.Net.WebSocket/)
- [Discord.Net.Webhook](https://www.nuget.org/packages/Discord.Net.Webhook/)

The following provider is available for platforms not supporting .NET Standard 1.3:
- [Discord.Net.Providers.WS4Net](https://www.nuget.org/packages/Discord.Net.Providers.WS4Net/)

### Unstable (MyGet)
Nightly builds are available through our MyGet feed (`https://www.myget.org/F/discord-net/api/v3/index.json`).

@@ -41,5 +37,4 @@ The .NET Core workload must be selected during Visual Studio installation.
## Known Issues

### WebSockets (Win7 and earlier)
.NET Core 1.1 does not support WebSockets on Win7 and earlier. It's recommended to use the Discord.Net.Providers.WS4Net package until this is resolved.
Track the issue [here](https://github.com/dotnet/corefx/issues/9503).
.NET Core 1.1 does not support WebSockets on Win7 and earlier. This issue has been fixed since the release of .NET Core 2.1. It is recommended to target .NET Core 2.1 or above for your project if you wish to run your bot on legacy platforms; alternatively, you may choose to install the [Discord.Net.Providers.WS4Net](https://www.nuget.org/packages/Discord.Net.Providers.WS4Net/) package.

+ 1
- 1
src/Discord.Net.Commands/Builders/ModuleBuilder.cs View File

@@ -120,7 +120,7 @@ namespace Discord.Commands.Builders
if (Name == null)
Name = _aliases[0];

if (TypeInfo != null)
if (TypeInfo != null && !TypeInfo.IsAbstract)
{
var moduleInstance = ReflectionUtils.CreateObject<IModuleBase>(TypeInfo, service, services);
moduleInstance.OnModuleBuilding(service, this);


+ 13
- 11
src/Discord.Net.Commands/Builders/ParameterBuilder.cs View File

@@ -45,14 +45,7 @@ namespace Discord.Commands.Builders

internal void SetType(Type type)
{
var readers = Command.Module.Service.GetTypeReaders(type);
if (readers != null)
TypeReader = readers.FirstOrDefault().Value;
else
TypeReader = Command.Module.Service.GetDefaultTypeReader(type);

if (TypeReader == null)
throw new InvalidOperationException($"{type} does not have a TypeReader registered for it. Parameter: {Name} in {Command.PrimaryAlias}");
TypeReader = GetReader(type);

if (type.GetTypeInfo().IsValueType)
DefaultValue = Activator.CreateInstance(type);
@@ -60,7 +53,16 @@ namespace Discord.Commands.Builders
type = ParameterType.GetElementType();
ParameterType = type;
}

private TypeReader GetReader(Type type)
{
var readers = Command.Module.Service.GetTypeReaders(type);
if (readers != null)
return readers.FirstOrDefault().Value;
else
return Command.Module.Service.GetDefaultTypeReader(type);
}

public ParameterBuilder WithSummary(string summary)
{
Summary = summary;
@@ -100,10 +102,10 @@ namespace Discord.Commands.Builders

internal ParameterInfo Build(CommandInfo info)
{
if (TypeReader == null)
if ((TypeReader ?? (TypeReader = GetReader(ParameterType))) == null)
throw new InvalidOperationException($"No type reader found for type {ParameterType.Name}, one must be specified");

return new ParameterInfo(this, info, Command.Module.Service);
}
}
}
}

+ 12
- 2
src/Discord.Net.Commands/CommandService.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -262,7 +262,7 @@ namespace Discord.Commands
/// <param name="replaceDefault">If <paramref name="reader"/> should replace the default <see cref="TypeReader"/> for <paramref name="type"/> if one exists.</param>
public void AddTypeReader(Type type, TypeReader reader, bool replaceDefault)
{
if (replaceDefault && _defaultTypeReaders.ContainsKey(type))
if (replaceDefault && HasDefaultTypeReader(type))
{
_defaultTypeReaders.AddOrUpdate(type, reader, (k, v) => reader);
if (type.GetTypeInfo().IsValueType)
@@ -281,6 +281,16 @@ namespace Discord.Commands
AddNullableTypeReader(type, reader);
}
}
internal bool HasDefaultTypeReader(Type type)
{
if (_defaultTypeReaders.ContainsKey(type))
return true;

var typeInfo = type.GetTypeInfo();
if (typeInfo.IsEnum)
return true;
return _entityTypeReaders.Any(x => type == x.Item1 || typeInfo.ImplementedInterfaces.Contains(x.Item2));
}
internal void AddNullableTypeReader(Type valueType, TypeReader valueTypeReader)
{
var readers = _typeReaders.GetOrAdd(typeof(Nullable<>).MakeGenericType(valueType), x => new ConcurrentDictionary<Type, TypeReader>());


+ 2
- 2
src/Discord.Net.Commands/Extensions/MessageExtensions.cs View File

@@ -1,4 +1,4 @@
using System;
using System;

namespace Discord.Commands
{
@@ -43,4 +43,4 @@ namespace Discord.Commands
return false;
}
}
}
}

+ 4
- 1
src/Discord.Net.Commands/Results/ParseResult.cs View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Discord.Commands
@@ -53,6 +54,8 @@ namespace Discord.Commands

public static ParseResult FromError(CommandError error, string reason)
=> new ParseResult(null, null, error, reason);
public static ParseResult FromError(Exception ex)
=> FromError(CommandError.Exception, ex.Message);
public static ParseResult FromError(IResult result)
=> new ParseResult(null, null, result.Error, result.ErrorReason);



+ 4
- 1
src/Discord.Net.Commands/Results/PreconditionGroupResult.cs View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Discord.Commands
@@ -18,6 +19,8 @@ namespace Discord.Commands
=> new PreconditionGroupResult(null, null, null);
public static PreconditionGroupResult FromError(string reason, ICollection<PreconditionResult> preconditions)
=> new PreconditionGroupResult(CommandError.UnmetPrecondition, reason, preconditions);
public static new PreconditionGroupResult FromError(Exception ex)
=> new PreconditionGroupResult(CommandError.Exception, ex.Message, null);
public static new PreconditionGroupResult FromError(IResult result) //needed?
=> new PreconditionGroupResult(result.Error, result.ErrorReason, null);



+ 4
- 1
src/Discord.Net.Commands/Results/PreconditionResult.cs View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;

namespace Discord.Commands
{
@@ -20,6 +21,8 @@ namespace Discord.Commands
=> new PreconditionResult(null, null);
public static PreconditionResult FromError(string reason)
=> new PreconditionResult(CommandError.UnmetPrecondition, reason);
public static PreconditionResult FromError(Exception ex)
=> new PreconditionResult(CommandError.Exception, ex.Message);
public static PreconditionResult FromError(IResult result)
=> new PreconditionResult(result.Error, result.ErrorReason);



+ 4
- 1
src/Discord.Net.Commands/Results/SearchResult.cs View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Discord.Commands
@@ -26,6 +27,8 @@ namespace Discord.Commands
=> new SearchResult(text, commands, null, null);
public static SearchResult FromError(CommandError error, string reason)
=> new SearchResult(null, null, error, reason);
public static SearchResult FromError(Exception ex)
=> FromError(CommandError.Exception, ex.Message);
public static SearchResult FromError(IResult result)
=> new SearchResult(null, null, result.Error, result.ErrorReason);



+ 2
- 0
src/Discord.Net.Commands/Results/TypeReaderResult.cs View File

@@ -50,6 +50,8 @@ namespace Discord.Commands
=> new TypeReaderResult(values, null, null);
public static TypeReaderResult FromError(CommandError error, string reason)
=> new TypeReaderResult(null, error, reason);
public static TypeReaderResult FromError(Exception ex)
=> FromError(CommandError.Exception, ex.Message);
public static TypeReaderResult FromError(IResult result)
=> new TypeReaderResult(null, result.Error, result.ErrorReason);



+ 2
- 2
src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,7 +9,7 @@ namespace Discord
/// <summary>
/// Represents an entry in an audit log
/// </summary>
public interface IAuditLogEntry : IEntity<ulong>
public interface IAuditLogEntry : ISnowflakeEntity
{
/// <summary>
/// The action which occured to create this entry


src/Discord.Net.Rest/Entities/Channels/ChannelType.cs → src/Discord.Net.Core/Entities/Channels/ChannelType.cs View File


+ 10
- 1
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -120,6 +120,15 @@ namespace Discord

/// <summary> Gets a collection of all invites to this guild. </summary>
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null);
/// <summary>
/// Gets the vanity invite URL of this guild.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// An awaitable <see cref="Task"/> containing the partial metadata of the vanity invite found within
/// this guild.
/// </returns>
Task<IInviteMetadata> GetVanityInviteAsync(RequestOptions options = null);

/// <summary> Gets the role in this guild with the provided id, or null if not found. </summary>
IRole GetRole(ulong id);
@@ -140,7 +149,7 @@ namespace Discord
Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null);

/// <summary> Gets the specified number of audit log entries for this guild. </summary>
Task<IReadOnlyCollection<IAuditLogEntry>> GetAuditLogAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch,
Task<IReadOnlyCollection<IAuditLogEntry>> GetAuditLogsAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch,
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);

/// <summary> Gets the webhook in this guild with the provided id, or null if not found. </summary>


+ 3
- 3
src/Discord.Net.Core/Entities/Invites/IInvite.cs View File

@@ -1,5 +1,3 @@
using System.Threading.Tasks;

namespace Discord
{
public interface IInvite : IEntity<string>, IDeletable
@@ -11,6 +9,8 @@ namespace Discord

/// <summary> Gets the channel this invite is linked to. </summary>
IChannel Channel { get; }
/// <summary> Gets the type of the channel this invite is linked to. </summary>
ChannelType ChannelType { get; }
/// <summary> Gets the id of the channel this invite is linked to. </summary>
ulong ChannelId { get; }
/// <summary> Gets the name of the channel this invite is linked to. </summary>
@@ -19,7 +19,7 @@ namespace Discord
/// <summary> Gets the guild this invite is linked to. </summary>
IGuild Guild { get; }
/// <summary> Gets the id of the guild this invite is linked to. </summary>
ulong GuildId { get; }
ulong? GuildId { get; }
/// <summary> Gets the name of the guild this invite is linked to. </summary>
string GuildName { get; }
/// <summary> Gets the approximated count of online members in the guild. </summary>


+ 4
- 4
src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs View File

@@ -1,4 +1,4 @@
using System;
using System;

namespace Discord
{
@@ -15,8 +15,8 @@ namespace Discord
/// <summary> Gets the max amount of times this invite may be used, or null if there is no limit. </summary>
int? MaxUses { get; }
/// <summary> Gets the amount of times this invite has been used. </summary>
int Uses { get; }
int? Uses { get; }
/// <summary> Gets when this invite was created. </summary>
DateTimeOffset CreatedAt { get; }
DateTimeOffset? CreatedAt { get; }
}
}
}

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

@@ -1,4 +1,4 @@
using System;
using System;

namespace Discord
{
@@ -30,6 +30,7 @@ namespace Discord
DeafenMembers = 0x00_80_00_00,
MoveMembers = 0x01_00_00_00,
UseVAD = 0x02_00_00_00,
PrioritySpeaker = 0x00_00_01_00,

// More General
ManageRoles = 0x10_00_00_00,


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

@@ -12,7 +12,7 @@ namespace Discord
/// <summary> Gets a ChannelPermissions that grants all permissions for text channels. </summary>
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_0000000010000_010001);
public static readonly ChannelPermissions Voice = new ChannelPermissions(0b00100_1111110_0000000010100_010001);
/// <summary> Gets a ChannelPermissions that grants all permissions for category channels. </summary>
public static readonly ChannelPermissions Category = new ChannelPermissions(0b01100_1111110_1111111110001_010001);
/// <summary> Gets a ChannelPermissions that grants all permissions for direct message channels. </summary>
@@ -78,6 +78,8 @@ namespace Discord
public bool MoveMembers => Permissions.GetValue(RawValue, ChannelPermission.MoveMembers);
/// <summary> If True, a user may use voice-activity-detection rather than push-to-talk. </summary>
public bool UseVAD => Permissions.GetValue(RawValue, ChannelPermission.UseVAD);
/// <summary> If True, a user may use priority speaker in a voice channel. </summary>
public bool PrioritySpeaker => Permissions.GetValue(RawValue, ChannelPermission.PrioritySpeaker);

/// <summary> If True, a user may adjust role permissions. This also implictly grants all other permissions. </summary>
public bool ManageRoles => Permissions.GetValue(RawValue, ChannelPermission.ManageRoles);
@@ -106,6 +108,7 @@ namespace Discord
bool? deafenMembers = null,
bool? moveMembers = null,
bool? useVoiceActivation = null,
bool? prioritySpeaker = null,
bool? manageRoles = null,
bool? manageWebhooks = null)
{
@@ -129,6 +132,7 @@ namespace Discord
Permissions.SetValue(ref value, deafenMembers, ChannelPermission.DeafenMembers);
Permissions.SetValue(ref value, moveMembers, ChannelPermission.MoveMembers);
Permissions.SetValue(ref value, useVoiceActivation, ChannelPermission.UseVAD);
Permissions.SetValue(ref value, prioritySpeaker, ChannelPermission.PrioritySpeaker);
Permissions.SetValue(ref value, manageRoles, ChannelPermission.ManageRoles);
Permissions.SetValue(ref value, manageWebhooks, ChannelPermission.ManageWebhooks);

@@ -155,11 +159,12 @@ namespace Discord
bool deafenMembers = false,
bool moveMembers = false,
bool useVoiceActivation = false,
bool prioritySpeaker = false,
bool manageRoles = false,
bool manageWebhooks = false)
: this(0, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages,
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect,
speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, manageRoles, manageWebhooks)
speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, prioritySpeaker, manageRoles, manageWebhooks)
{ }

/// <summary> Creates a new ChannelPermissions from this one, changing the provided non-null permissions. </summary>
@@ -182,6 +187,7 @@ namespace Discord
bool? deafenMembers = null,
bool? moveMembers = null,
bool? useVoiceActivation = null,
bool? prioritySpeaker = null,
bool? manageRoles = null,
bool? manageWebhooks = null)
=> new ChannelPermissions(RawValue,
@@ -203,6 +209,7 @@ namespace Discord
deafenMembers,
moveMembers,
useVoiceActivation,
prioritySpeaker,
manageRoles,
manageWebhooks);



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

@@ -35,6 +35,7 @@ namespace Discord
DeafenMembers = 0x00_80_00_00,
MoveMembers = 0x01_00_00_00,
UseVAD = 0x02_00_00_00,
PrioritySpeaker = 0x00_00_01_00,

// General 2
ChangeNickname = 0x04_00_00_00,


+ 9
- 2
src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs View File

@@ -12,7 +12,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_1111111110011_111111);
public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_1111111110111_111111);

/// <summary> Gets a packed value representing all the permissions in this GuildPermissions. </summary>
public ulong RawValue { get; }
@@ -69,6 +69,8 @@ namespace Discord
public bool MoveMembers => Permissions.GetValue(RawValue, GuildPermission.MoveMembers);
/// <summary> If True, a user may use voice-activity-detection rather than push-to-talk. </summary>
public bool UseVAD => Permissions.GetValue(RawValue, GuildPermission.UseVAD);
/// <summary> If True, a user may use priority speaker in a voice channel. </summary>
public bool PrioritySpeaker => Permissions.GetValue(RawValue, ChannelPermission.PrioritySpeaker);

/// <summary> If True, a user may change their own nickname. </summary>
public bool ChangeNickname => Permissions.GetValue(RawValue, GuildPermission.ChangeNickname);
@@ -108,6 +110,7 @@ namespace Discord
bool? deafenMembers = null,
bool? moveMembers = null,
bool? useVoiceActivation = null,
bool? prioritySpeaker = null,
bool? changeNickname = null,
bool? manageNicknames = null,
bool? manageRoles = null,
@@ -139,6 +142,7 @@ namespace Discord
Permissions.SetValue(ref value, deafenMembers, GuildPermission.DeafenMembers);
Permissions.SetValue(ref value, moveMembers, GuildPermission.MoveMembers);
Permissions.SetValue(ref value, useVoiceActivation, GuildPermission.UseVAD);
Permissions.SetValue(ref value, prioritySpeaker, GuildPermission.PrioritySpeaker);
Permissions.SetValue(ref value, changeNickname, GuildPermission.ChangeNickname);
Permissions.SetValue(ref value, manageNicknames, GuildPermission.ManageNicknames);
Permissions.SetValue(ref value, manageRoles, GuildPermission.ManageRoles);
@@ -173,6 +177,7 @@ namespace Discord
bool deafenMembers = false,
bool moveMembers = false,
bool useVoiceActivation = false,
bool prioritySpeaker = false,
bool changeNickname = false,
bool manageNicknames = false,
bool manageRoles = false,
@@ -203,6 +208,7 @@ namespace Discord
deafenMembers: deafenMembers,
moveMembers: moveMembers,
useVoiceActivation: useVoiceActivation,
prioritySpeaker: prioritySpeaker,
changeNickname: changeNickname,
manageNicknames: manageNicknames,
manageWebhooks: manageWebhooks,
@@ -234,6 +240,7 @@ namespace Discord
bool? deafenMembers = null,
bool? moveMembers = null,
bool? useVoiceActivation = null,
bool? prioritySpeaker = null,
bool? changeNickname = null,
bool? manageNicknames = null,
bool? manageRoles = null,
@@ -242,7 +249,7 @@ namespace Discord
=> new GuildPermissions(RawValue, createInstantInvite, kickMembers, banMembers, administrator, manageChannels, manageGuild, addReactions,
viewAuditLog, viewChannel, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles,
readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, moveMembers,
useVoiceActivation, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis);
useVoiceActivation, prioritySpeaker, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis);

public bool Has(GuildPermission permission) => Permissions.GetValue(RawValue, permission);



+ 11
- 0
src/Discord.Net.Core/Extensions/MessageExtensions.cs View File

@@ -0,0 +1,11 @@
namespace Discord
{
public static class MessageExtensions
{
public static string GetJumpUrl(this IMessage msg)
{
var channel = msg.Channel;
return $"https://discordapp.com/channels/{(channel is IDMChannel ? "@me" : $"{(channel as ITextChannel).GuildId}")}/{channel.Id}/{msg.Id}";
}
}
}

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

@@ -27,7 +27,7 @@ namespace Discord
Task<IReadOnlyCollection<IGuild>> GetGuildsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null);
Task<IInvite> GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null);
Task<IInvite> GetInviteAsync(string inviteId, RequestOptions options = null);

Task<IUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
Task<IUser> GetUserAsync(string username, string discriminator, RequestOptions options = null);


+ 1
- 1
src/Discord.Net.Rest/API/Common/Invite.cs View File

@@ -8,7 +8,7 @@ namespace Discord.API
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("guild")]
public InviteGuild Guild { get; set; }
public Optional<InviteGuild> Guild { get; set; }
[JsonProperty("channel")]
public InviteChannel Channel { get; set; }
[JsonProperty("approximate_presence_count")]


+ 2
- 2
src/Discord.Net.Rest/API/Common/InviteChannel.cs View File

@@ -1,4 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API
@@ -10,6 +10,6 @@ namespace Discord.API
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
public int Type { get; set; }
}
}

+ 5
- 5
src/Discord.Net.Rest/API/Common/InviteMetadata.cs View File

@@ -1,4 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable CS1591
using Newtonsoft.Json;
using System;

@@ -9,15 +9,15 @@ namespace Discord.API
[JsonProperty("inviter")]
public User Inviter { get; set; }
[JsonProperty("uses")]
public int Uses { get; set; }
public Optional<int> Uses { get; set; }
[JsonProperty("max_uses")]
public int MaxUses { get; set; }
public Optional<int> MaxUses { get; set; }
[JsonProperty("max_age")]
public int MaxAge { get; set; }
public Optional<int> MaxAge { get; set; }
[JsonProperty("temporary")]
public bool Temporary { get; set; }
[JsonProperty("created_at")]
public DateTimeOffset CreatedAt { get; set; }
public Optional<DateTimeOffset> CreatedAt { get; set; }
[JsonProperty("revoked")]
public bool Revoked { get; set; }
}


+ 0
- 7
src/Discord.Net.Rest/API/Rest/GetInviteParams.cs View File

@@ -1,7 +0,0 @@
namespace Discord.API.Rest
{
internal class GetInviteParams
{
public Optional<bool?> WithCounts { get; set; }
}
}

+ 1
- 1
src/Discord.Net.Rest/BaseDiscordClient.cs View File

@@ -148,7 +148,7 @@ namespace Discord.Rest
Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
=> Task.FromResult<IReadOnlyCollection<IConnection>>(ImmutableArray.Create<IConnection>());

Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options)
=> Task.FromResult<IInvite>(null);

Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)


+ 2
- 6
src/Discord.Net.Rest/ClientHelper.cs View File

@@ -51,13 +51,9 @@ namespace Discord.Rest
}
public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client,
string inviteId, bool withCount, RequestOptions options)
string inviteId, RequestOptions options)
{
var args = new GetInviteParams
{
WithCounts = withCount
};
var model = await client.ApiClient.GetInviteAsync(inviteId, args, options).ConfigureAwait(false);
var model = await client.ApiClient.GetInviteAsync(inviteId, options).ConfigureAwait(false);
if (model != null)
return RestInviteMetadata.Create(client, null, null, model);
return null;


+ 10
- 4
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -906,7 +906,7 @@ namespace Discord.API
}

//Guild Invites
public async Task<InviteMetadata> GetInviteAsync(string inviteId, GetInviteParams args, RequestOptions options = null)
public async Task<InviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null)
{
Preconditions.NotNullOrEmpty(inviteId, nameof(inviteId));
options = RequestOptions.CreateOrClone(options);
@@ -919,14 +919,20 @@ namespace Discord.API
if (index >= 0)
inviteId = inviteId.Substring(index + 1);

var withCounts = args.WithCounts.GetValueOrDefault(false);

try
{
return await SendAsync<InviteMetadata>("GET", () => $"invites/{inviteId}?with_counts={withCounts}", new BucketIds(), options: options).ConfigureAwait(false);
return await SendAsync<InviteMetadata>("GET", () => $"invites/{inviteId}?with_counts=true", new BucketIds(), options: options).ConfigureAwait(false);
}
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
}
public async Task<InviteMetadata> GetVanityInviteAsync(ulong guildId, RequestOptions options = null)
{
Preconditions.NotEqual(guildId, 0, nameof(guildId));
options = RequestOptions.CreateOrClone(options);

var ids = new BucketIds(guildId: guildId);
return await SendAsync<InviteMetadata>("GET", () => $"guilds/{guildId}/vanity-url", ids, options: options).ConfigureAwait(false);
}
public async Task<IReadOnlyCollection<InviteMetadata>> GetGuildInvitesAsync(ulong guildId, RequestOptions options = null)
{
Preconditions.NotEqual(guildId, 0, nameof(guildId));


+ 4
- 4
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -56,8 +56,8 @@ namespace Discord.Rest
=> ClientHelper.GetConnectionsAsync(this, options);

/// <inheritdoc />
public Task<RestInviteMetadata> GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null)
=> ClientHelper.GetInviteAsync(this, inviteId, withCount, options);
public Task<RestInviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null)
=> ClientHelper.GetInviteAsync(this, inviteId, options);

/// <inheritdoc />
public Task<RestGuild> GetGuildAsync(ulong id, RequestOptions options = null)
@@ -131,8 +131,8 @@ namespace Discord.Rest
async Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
=> await GetConnectionsAsync(options).ConfigureAwait(false);

async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
=> await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false);
async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options)
=> await GetInviteAsync(inviteId, options).ConfigureAwait(false);

async Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)
{


+ 18
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs View File

@@ -0,0 +1,18 @@
namespace Discord.Rest
{
public struct MemberInfo
{
internal MemberInfo(string nick, bool? deaf, bool? mute, string avatar_hash)
{
Nickname = nick;
Deaf = deaf;
Mute = mute;
AvatarHash = avatar_hash;
}

public string Nickname { get; }
public bool? Deaf { get; }
public bool? Mute { get; }
public string AvatarHash { get; }
}
}

+ 23
- 9
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs View File

@@ -8,28 +8,42 @@ namespace Discord.Rest
{
public class MemberUpdateAuditLogData : IAuditLogData
{
private MemberUpdateAuditLogData(IUser target, string newNick, string oldNick)
private MemberUpdateAuditLogData(IUser target, MemberInfo before, MemberInfo after)
{
Target = target;
NewNick = newNick;
OldNick = oldNick;
Before = before;
After = after;
}

internal static MemberUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "nick");
var changes = entry.Changes;

var newNick = changes.NewValue?.ToObject<string>();
var oldNick = changes.OldValue?.ToObject<string>();
var nickModel = changes.FirstOrDefault(x => x.ChangedProperty == "nick");
var deafModel = changes.FirstOrDefault(x => x.ChangedProperty == "deaf");
var muteModel = changes.FirstOrDefault(x => x.ChangedProperty == "mute");
var avatarModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash");

string oldNick = nickModel?.OldValue?.ToObject<string>(),
newNick = nickModel?.NewValue?.ToObject<string>();
bool? oldDeaf = deafModel?.OldValue?.ToObject<bool>(),
newDeaf = deafModel?.NewValue?.ToObject<bool>();
bool? oldMute = muteModel?.OldValue?.ToObject<bool>(),
newMute = muteModel?.NewValue?.ToObject<bool>();
string oldAvatar = avatarModel?.OldValue?.ToObject<string>(),
newAvatar = avatarModel?.NewValue?.ToObject<string>();

var targetInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
var user = RestUser.Create(discord, targetInfo);

return new MemberUpdateAuditLogData(user, newNick, oldNick);
var before = new MemberInfo(oldNick, oldDeaf, oldMute, oldAvatar);
var after = new MemberInfo(newNick, newDeaf, newMute, newAvatar);

return new MemberUpdateAuditLogData(user, before, after);
}

public IUser Target { get; }
public string NewNick { get; }
public string OldNick { get; }
public MemberInfo Before { get; }
public MemberInfo After { get; }
}
}

+ 4
- 1
src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs View File

@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;
@@ -26,6 +27,8 @@ namespace Discord.Rest
return new RestAuditLogEntry(discord, fullLog, model, user);
}

/// <inheritdoc/>
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
/// <inheritdoc/>
public ActionType Action { get; }
/// <inheritdoc/>


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

@@ -210,6 +210,12 @@ namespace Discord.Rest
var models = await client.ApiClient.GetGuildInvitesAsync(guild.Id, options).ConfigureAwait(false);
return models.Select(x => RestInviteMetadata.Create(client, guild, null, x)).ToImmutableArray();
}
public static async Task<RestInviteMetadata> GetVanityInviteAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options)
{
var model = await client.ApiClient.GetVanityInviteAsync(guild.Id, options).ConfigureAwait(false);
return RestInviteMetadata.Create(client, guild, null, model);
}

//Roles
public static async Task<RestRole> CreateRoleAsync(IGuild guild, BaseDiscordClient client,


+ 13
- 1
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -238,6 +238,15 @@ namespace Discord.Rest
//Invites
public Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> GuildHelper.GetInvitesAsync(this, Discord, options);
/// <summary>
/// Gets the vanity invite URL of this guild.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A partial metadata of the vanity invite found within this guild.
/// </returns>
public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null)
=> GuildHelper.GetVanityInviteAsync(this, Discord, options);

//Roles
public RestRole GetRole(ulong id)
@@ -397,6 +406,9 @@ namespace Discord.Rest

async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options)
=> await GetInvitesAsync(options).ConfigureAwait(false);
/// <inheritdoc />
async Task<IInviteMetadata> IGuild.GetVanityInviteAsync(RequestOptions options)
=> await GetVanityInviteAsync(options).ConfigureAwait(false);

IRole IGuild.GetRole(ulong id)
=> GetRole(id);
@@ -433,7 +445,7 @@ namespace Discord.Rest
}
Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); }

async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options)
async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options)
{
if (cacheMode == CacheMode.AllowDownload)
return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();


+ 8
- 10
src/Discord.Net.Rest/Entities/Invites/RestInvite.cs View File

@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Discord.API.Rest;
using Model = Discord.API.Invite;

namespace Discord.Rest
@@ -9,14 +8,15 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestInvite : RestEntity<string>, IInvite, IUpdateable
{
public ChannelType ChannelType { get; private set; }
public string ChannelName { get; private set; }
public string GuildName { get; private set; }
public int? PresenceCount { get; private set; }
public int? MemberCount { get; private set; }
public ulong ChannelId { get; private set; }
public ulong GuildId { get; private set; }
internal IChannel Channel { get; private set; }
internal IGuild Guild { get; private set; }
public ulong? GuildId { get; private set; }
internal IChannel Channel { get; }
internal IGuild Guild { get; }

public string Code => Id;
public string Url => $"{DiscordConfig.InviteUrl}{Code}";
@@ -35,20 +35,18 @@ namespace Discord.Rest
}
internal void Update(Model model)
{
GuildId = model.Guild.Id;
GuildId = model.Guild.IsSpecified ? model.Guild.Value.Id : default(ulong?);
ChannelId = model.Channel.Id;
GuildName = model.Guild.Name;
GuildName = model.Guild.IsSpecified ? model.Guild.Value.Name : null;
ChannelName = model.Channel.Name;
MemberCount = model.MemberCount.IsSpecified ? model.MemberCount.Value : null;
PresenceCount = model.PresenceCount.IsSpecified ? model.PresenceCount.Value : null;
ChannelType = (ChannelType)model.Channel.Type;
}
public async Task UpdateAsync(RequestOptions options = null)
{
var args = new GetInviteParams();
if (MemberCount != null || PresenceCount != null)
args.WithCounts = true;
var model = await Discord.ApiClient.GetInviteAsync(Code, args, options).ConfigureAwait(false);
var model = await Discord.ApiClient.GetInviteAsync(Code, options).ConfigureAwait(false);
Update(model);
}
public Task DeleteAsync(RequestOptions options = null)


+ 8
- 8
src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs View File

@@ -1,20 +1,20 @@
using System;
using System;
using Model = Discord.API.InviteMetadata;

namespace Discord.Rest
{
public class RestInviteMetadata : RestInvite, IInviteMetadata
{
private long _createdAtTicks;
private long? _createdAtTicks;

public bool IsRevoked { get; private set; }
public bool IsTemporary { get; private set; }
public int? MaxAge { get; private set; }
public int? MaxUses { get; private set; }
public int Uses { get; private set; }
public int? Uses { get; private set; }
public RestUser Inviter { get; private set; }

public DateTimeOffset CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks);
public DateTimeOffset? CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks);

internal RestInviteMetadata(BaseDiscordClient discord, IGuild guild, IChannel channel, string id)
: base(discord, guild, channel, id)
@@ -32,10 +32,10 @@ namespace Discord.Rest
Inviter = model.Inviter != null ? RestUser.Create(Discord, model.Inviter) : null;
IsRevoked = model.Revoked;
IsTemporary = model.Temporary;
MaxAge = model.MaxAge != 0 ? model.MaxAge : (int?)null;
MaxUses = model.MaxUses;
Uses = model.Uses;
_createdAtTicks = model.CreatedAt.UtcTicks;
MaxAge = model.MaxAge.IsSpecified ? model.MaxAge.Value : (int?)null;
MaxUses = model.MaxUses.IsSpecified ? model.MaxUses.Value : (int?)null;
Uses = model.Uses.IsSpecified ? model.Uses.Value : (int?)null;
_createdAtTicks = model.CreatedAt.IsSpecified ? model.CreatedAt.Value.UtcTicks : (long?)null;
}

IUser IInviteMetadata.Inviter => Inviter;


+ 4
- 4
src/Discord.Net.WebSocket/BaseSocketClient.cs View File

@@ -55,8 +55,8 @@ namespace Discord.WebSocket
public Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(RequestOptions options = null)
=> ClientHelper.GetConnectionsAsync(this, options ?? RequestOptions.Default);
/// <inheritdoc />
public Task<RestInviteMetadata> GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null)
=> ClientHelper.GetInviteAsync(this, inviteId, withCount, options ?? RequestOptions.Default);
public Task<RestInviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null)
=> ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default);
// IDiscordClient
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
@@ -70,8 +70,8 @@ namespace Discord.WebSocket
async Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
=> await GetConnectionsAsync(options).ConfigureAwait(false);

async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
=> await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false);
async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options)
=> await GetInviteAsync(inviteId, options).ConfigureAwait(false);

Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuild>(GetGuild(id));


+ 2
- 2
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -328,8 +328,8 @@ namespace Discord.WebSocket
async Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
=> await GetConnectionsAsync().ConfigureAwait(false);

async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
=> await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false);
async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options)
=> await GetInviteAsync(inviteId, options).ConfigureAwait(false);

Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuild>(GetGuild(id));


+ 5
- 2
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -1513,6 +1513,9 @@ namespace Discord.WebSocket
case "MESSAGE_ACK":
await _gatewayLogger.DebugAsync("Ignored Dispatch (MESSAGE_ACK)").ConfigureAwait(false);
break;
case "PRESENCES_REPLACE":
await _gatewayLogger.DebugAsync("Ignored Dispatch (PRESENCES_REPLACE)").ConfigureAwait(false);
break;
case "USER_SETTINGS_UPDATE":
await _gatewayLogger.DebugAsync("Ignored Dispatch (USER_SETTINGS_UPDATE)").ConfigureAwait(false);
break;
@@ -1819,8 +1822,8 @@ namespace Discord.WebSocket
async Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
=> await GetConnectionsAsync().ConfigureAwait(false);

async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
=> await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false);
async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options)
=> await GetInviteAsync(inviteId, options).ConfigureAwait(false);

Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuild>(GetGuild(id));


+ 13
- 1
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -345,6 +345,15 @@ namespace Discord.WebSocket
//Invites
public Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> GuildHelper.GetInvitesAsync(this, Discord, options);
/// <summary>
/// Gets the vanity invite URL of this guild.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A partial metadata of the vanity invite found within this guild.
/// </returns>
public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null)
=> GuildHelper.GetVanityInviteAsync(this, Discord, options);

//Roles
public SocketRole GetRole(ulong id)
@@ -700,6 +709,9 @@ namespace Discord.WebSocket

async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options)
=> await GetInvitesAsync(options).ConfigureAwait(false);
/// <inheritdoc />
async Task<IInviteMetadata> IGuild.GetVanityInviteAsync(RequestOptions options)
=> await GetVanityInviteAsync(options).ConfigureAwait(false);

IRole IGuild.GetRole(ulong id)
=> GetRole(id);
@@ -715,7 +727,7 @@ namespace Discord.WebSocket
Task<IGuildUser> IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(Owner);

async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options)
async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options)
{
if (cacheMode == CacheMode.AllowDownload)
return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();


Loading…
Cancel
Save