From 4bc06a0a54477e756caa18d3030e5a8e7fa20d10 Mon Sep 17 00:00:00 2001 From: HelpfulStranger999 Date: Mon, 2 Jul 2018 15:29:42 -0500 Subject: [PATCH 01/12] Patch lazy default readers not getting replaced (#1083) --- src/Discord.Net.Commands/CommandService.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 8e5297e49..6fd5d38ad 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; @@ -262,7 +262,7 @@ namespace Discord.Commands /// If should replace the default for if one exists. 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()); From ffe994a9dff1ea3bca63673d332a28b88231d38d Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Tue, 3 Jul 2018 05:02:38 +0800 Subject: [PATCH 02/12] Mark guild optional in invite & general invite improvement (#1094) * Mark guild as optional for invite * Mark partial InviteMetadata members as Optional * Some of them aren't sent when requesting through the general GET invite endpoint * Remove GetInviteParams * It was kinda stupid in the first place, might as well always get the count instead of having to ask the user whether they want the two fields filled or not. * Add ChannelType property * Add vanity invite support --- .../Entities/Channels/ChannelType.cs | 0 src/Discord.Net.Core/Entities/Guilds/IGuild.cs | 9 +++++++++ .../Entities/Invites/IInvite.cs | 6 +++--- .../Entities/Invites/IInviteMetadata.cs | 8 ++++---- src/Discord.Net.Rest/API/Common/Invite.cs | 2 +- .../API/Common/InviteChannel.cs | 4 ++-- .../API/Common/InviteMetadata.cs | 10 +++++----- .../API/Rest/GetInviteParams.cs | 7 ------- src/Discord.Net.Rest/ClientHelper.cs | 8 ++------ src/Discord.Net.Rest/DiscordRestApiClient.cs | 14 ++++++++++---- src/Discord.Net.Rest/DiscordRestClient.cs | 2 +- .../Entities/Guilds/GuildHelper.cs | 6 ++++++ .../Entities/Guilds/RestGuild.cs | 12 ++++++++++++ .../Entities/Invites/RestInvite.cs | 18 ++++++++---------- .../Entities/Invites/RestInviteMetadata.cs | 16 ++++++++-------- src/Discord.Net.WebSocket/BaseSocketClient.cs | 2 +- .../Entities/Guilds/SocketGuild.cs | 12 ++++++++++++ 17 files changed, 84 insertions(+), 52 deletions(-) rename src/{Discord.Net.Rest => Discord.Net.Core}/Entities/Channels/ChannelType.cs (100%) delete mode 100644 src/Discord.Net.Rest/API/Rest/GetInviteParams.cs diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelType.cs b/src/Discord.Net.Core/Entities/Channels/ChannelType.cs similarity index 100% rename from src/Discord.Net.Rest/Entities/Channels/ChannelType.cs rename to src/Discord.Net.Core/Entities/Channels/ChannelType.cs diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index 4c1c274d0..604945758 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -120,6 +120,15 @@ namespace Discord /// Gets a collection of all invites to this guild. Task> GetInvitesAsync(RequestOptions options = null); + /// + /// Gets the vanity invite URL of this guild. + /// + /// The options to be used when sending the request. + /// + /// An awaitable containing the partial metadata of the vanity invite found within + /// this guild. + /// + Task GetVanityInviteAsync(RequestOptions options = null); /// Gets the role in this guild with the provided id, or null if not found. IRole GetRole(ulong id); diff --git a/src/Discord.Net.Core/Entities/Invites/IInvite.cs b/src/Discord.Net.Core/Entities/Invites/IInvite.cs index 0ebb65679..1ab26de8f 100644 --- a/src/Discord.Net.Core/Entities/Invites/IInvite.cs +++ b/src/Discord.Net.Core/Entities/Invites/IInvite.cs @@ -1,5 +1,3 @@ -using System.Threading.Tasks; - namespace Discord { public interface IInvite : IEntity, IDeletable @@ -11,6 +9,8 @@ namespace Discord /// Gets the channel this invite is linked to. IChannel Channel { get; } + /// Gets the type of the channel this invite is linked to. + ChannelType ChannelType { get; } /// Gets the id of the channel this invite is linked to. ulong ChannelId { get; } /// Gets the name of the channel this invite is linked to. @@ -19,7 +19,7 @@ namespace Discord /// Gets the guild this invite is linked to. IGuild Guild { get; } /// Gets the id of the guild this invite is linked to. - ulong GuildId { get; } + ulong? GuildId { get; } /// Gets the name of the guild this invite is linked to. string GuildName { get; } /// Gets the approximated count of online members in the guild. diff --git a/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs b/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs index 1136e1678..0e026ab62 100644 --- a/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs +++ b/src/Discord.Net.Core/Entities/Invites/IInviteMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Discord { @@ -15,8 +15,8 @@ namespace Discord /// Gets the max amount of times this invite may be used, or null if there is no limit. int? MaxUses { get; } /// Gets the amount of times this invite has been used. - int Uses { get; } + int? Uses { get; } /// Gets when this invite was created. - DateTimeOffset CreatedAt { get; } + DateTimeOffset? CreatedAt { get; } } -} \ No newline at end of file +} diff --git a/src/Discord.Net.Rest/API/Common/Invite.cs b/src/Discord.Net.Rest/API/Common/Invite.cs index 1b35da870..649bc37ec 100644 --- a/src/Discord.Net.Rest/API/Common/Invite.cs +++ b/src/Discord.Net.Rest/API/Common/Invite.cs @@ -8,7 +8,7 @@ namespace Discord.API [JsonProperty("code")] public string Code { get; set; } [JsonProperty("guild")] - public InviteGuild Guild { get; set; } + public Optional Guild { get; set; } [JsonProperty("channel")] public InviteChannel Channel { get; set; } [JsonProperty("approximate_presence_count")] diff --git a/src/Discord.Net.Rest/API/Common/InviteChannel.cs b/src/Discord.Net.Rest/API/Common/InviteChannel.cs index ca9699067..f8f2a34f2 100644 --- a/src/Discord.Net.Rest/API/Common/InviteChannel.cs +++ b/src/Discord.Net.Rest/API/Common/InviteChannel.cs @@ -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; } } } diff --git a/src/Discord.Net.Rest/API/Common/InviteMetadata.cs b/src/Discord.Net.Rest/API/Common/InviteMetadata.cs index 586307523..ca019b79b 100644 --- a/src/Discord.Net.Rest/API/Common/InviteMetadata.cs +++ b/src/Discord.Net.Rest/API/Common/InviteMetadata.cs @@ -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 Uses { get; set; } [JsonProperty("max_uses")] - public int MaxUses { get; set; } + public Optional MaxUses { get; set; } [JsonProperty("max_age")] - public int MaxAge { get; set; } + public Optional MaxAge { get; set; } [JsonProperty("temporary")] public bool Temporary { get; set; } [JsonProperty("created_at")] - public DateTimeOffset CreatedAt { get; set; } + public Optional CreatedAt { get; set; } [JsonProperty("revoked")] public bool Revoked { get; set; } } diff --git a/src/Discord.Net.Rest/API/Rest/GetInviteParams.cs b/src/Discord.Net.Rest/API/Rest/GetInviteParams.cs deleted file mode 100644 index cb8d8f7fe..000000000 --- a/src/Discord.Net.Rest/API/Rest/GetInviteParams.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Discord.API.Rest -{ - internal class GetInviteParams - { - public Optional WithCounts { get; set; } - } -} diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index 0bba0d2c4..d8f481d15 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -51,13 +51,9 @@ namespace Discord.Rest } public static async Task 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; diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 85e04f962..2236dbbf8 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -906,7 +906,7 @@ namespace Discord.API } //Guild Invites - public async Task GetInviteAsync(string inviteId, GetInviteParams args, RequestOptions options = null) + public async Task 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("GET", () => $"invites/{inviteId}?with_counts={withCounts}", new BucketIds(), options: options).ConfigureAwait(false); + return await SendAsync("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 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("GET", () => $"guilds/{guildId}/vanity-url", ids, options: options).ConfigureAwait(false); + } public async Task> GetGuildInvitesAsync(ulong guildId, RequestOptions options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index 3a596624d..73028362f 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -57,7 +57,7 @@ namespace Discord.Rest /// public Task GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null) - => ClientHelper.GetInviteAsync(this, inviteId, withCount, options); + => ClientHelper.GetInviteAsync(this, inviteId, options); /// public Task GetGuildAsync(ulong id, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index c76b41a91..4bd0e9972 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -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 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 CreateRoleAsync(IGuild guild, BaseDiscordClient client, diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 357e22c85..9b3143268 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -238,6 +238,15 @@ namespace Discord.Rest //Invites public Task> GetInvitesAsync(RequestOptions options = null) => GuildHelper.GetInvitesAsync(this, Discord, options); + /// + /// Gets the vanity invite URL of this guild. + /// + /// The options to be used when sending the request. + /// + /// A partial metadata of the vanity invite found within this guild. + /// + public Task GetVanityInviteAsync(RequestOptions options = null) + => GuildHelper.GetVanityInviteAsync(this, Discord, options); //Roles public RestRole GetRole(ulong id) @@ -397,6 +406,9 @@ namespace Discord.Rest async Task> IGuild.GetInvitesAsync(RequestOptions options) => await GetInvitesAsync(options).ConfigureAwait(false); + /// + async Task IGuild.GetVanityInviteAsync(RequestOptions options) + => await GetVanityInviteAsync(options).ConfigureAwait(false); IRole IGuild.GetRole(ulong id) => GetRole(id); diff --git a/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs b/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs index 18698c626..050f117fb 100644 --- a/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs +++ b/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs @@ -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, 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) diff --git a/src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs b/src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs index 42aeb40aa..c7236be58 100644 --- a/src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs +++ b/src/Discord.Net.Rest/Entities/Invites/RestInviteMetadata.cs @@ -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; diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs index fb82fe14a..be6f3795d 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs @@ -56,7 +56,7 @@ namespace Discord.WebSocket => ClientHelper.GetConnectionsAsync(this, options ?? RequestOptions.Default); /// public Task GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null) - => ClientHelper.GetInviteAsync(this, inviteId, withCount, options ?? RequestOptions.Default); + => ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default); // IDiscordClient async Task IDiscordClient.GetApplicationInfoAsync(RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index f41f61a7c..680706713 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -345,6 +345,15 @@ namespace Discord.WebSocket //Invites public Task> GetInvitesAsync(RequestOptions options = null) => GuildHelper.GetInvitesAsync(this, Discord, options); + /// + /// Gets the vanity invite URL of this guild. + /// + /// The options to be used when sending the request. + /// + /// A partial metadata of the vanity invite found within this guild. + /// + public Task GetVanityInviteAsync(RequestOptions options = null) + => GuildHelper.GetVanityInviteAsync(this, Discord, options); //Roles public SocketRole GetRole(ulong id) @@ -700,6 +709,9 @@ namespace Discord.WebSocket async Task> IGuild.GetInvitesAsync(RequestOptions options) => await GetInvitesAsync(options).ConfigureAwait(false); + /// + async Task IGuild.GetVanityInviteAsync(RequestOptions options) + => await GetVanityInviteAsync(options).ConfigureAwait(false); IRole IGuild.GetRole(ulong id) => GetRole(id); From beb3d46e0866c3d1ee8fa8483576547e90b517c6 Mon Sep 17 00:00:00 2001 From: Christopher F Date: Mon, 2 Jul 2018 21:24:50 -0400 Subject: [PATCH 03/12] gateway: Ignore PRESENCES_REPLACE dispatch This dispatch is undocumented and only used by user accounts. --- src/Discord.Net.WebSocket/DiscordSocketClient.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 793d2b29c..412552d74 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -1512,6 +1512,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; From b2f00439524af9836818631f4bfa7c42e9076feb Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Wed, 11 Jul 2018 07:32:29 +0800 Subject: [PATCH 04/12] Fix typo in audit log interface declaration (#1104) --- src/Discord.Net.Core/Entities/Guilds/IGuild.cs | 2 +- src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs | 2 +- src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index 604945758..bbe7051cb 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -149,7 +149,7 @@ namespace Discord Task PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null); /// Gets the specified number of audit log entries for this guild. - Task> GetAuditLogAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, + Task> GetAuditLogsAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); /// Gets the webhook in this guild with the provided id, or null if not found. diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 9b3143268..9bf13fa07 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -445,7 +445,7 @@ namespace Discord.Rest } Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); } - async Task> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options) + async Task> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options) { if (cacheMode == CacheMode.AllowDownload) return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray(); diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index 680706713..bf33ef569 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -727,7 +727,7 @@ namespace Discord.WebSocket Task IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options) => Task.FromResult(Owner); - async Task> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options) + async Task> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options) { if (cacheMode == CacheMode.AllowDownload) return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray(); From 245806fe3da063b8d11c26ae3ea7723daab83797 Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Thu, 12 Jul 2018 08:44:00 +0800 Subject: [PATCH 05/12] Initial refactor (#1103) --- src/Discord.Net.Core/IDiscordClient.cs | 2 +- src/Discord.Net.Rest/BaseDiscordClient.cs | 2 +- src/Discord.Net.Rest/DiscordRestClient.cs | 6 +++--- src/Discord.Net.WebSocket/BaseSocketClient.cs | 6 +++--- src/Discord.Net.WebSocket/DiscordShardedClient.cs | 4 ++-- src/Discord.Net.WebSocket/DiscordSocketClient.cs | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs index 083c0b512..a383c37da 100644 --- a/src/Discord.Net.Core/IDiscordClient.cs +++ b/src/Discord.Net.Core/IDiscordClient.cs @@ -27,7 +27,7 @@ namespace Discord Task> GetGuildsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null); - Task GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null); + Task GetInviteAsync(string inviteId, RequestOptions options = null); Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetUserAsync(string username, string discriminator, RequestOptions options = null); diff --git a/src/Discord.Net.Rest/BaseDiscordClient.cs b/src/Discord.Net.Rest/BaseDiscordClient.cs index db8e2e691..f8642b96c 100644 --- a/src/Discord.Net.Rest/BaseDiscordClient.cs +++ b/src/Discord.Net.Rest/BaseDiscordClient.cs @@ -148,7 +148,7 @@ namespace Discord.Rest Task> IDiscordClient.GetConnectionsAsync(RequestOptions options) => Task.FromResult>(ImmutableArray.Create()); - Task IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options) + Task IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options) => Task.FromResult(null); Task IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options) diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index 73028362f..d4dee9f0a 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -56,7 +56,7 @@ namespace Discord.Rest => ClientHelper.GetConnectionsAsync(this, options); /// - public Task GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null) + public Task GetInviteAsync(string inviteId, RequestOptions options = null) => ClientHelper.GetInviteAsync(this, inviteId, options); /// @@ -131,8 +131,8 @@ namespace Discord.Rest async Task> IDiscordClient.GetConnectionsAsync(RequestOptions options) => await GetConnectionsAsync(options).ConfigureAwait(false); - async Task IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options) - => await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false); + async Task IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options) + => await GetInviteAsync(inviteId, options).ConfigureAwait(false); async Task IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options) { diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs index be6f3795d..a7d590b42 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs @@ -55,7 +55,7 @@ namespace Discord.WebSocket public Task> GetConnectionsAsync(RequestOptions options = null) => ClientHelper.GetConnectionsAsync(this, options ?? RequestOptions.Default); /// - public Task GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null) + public Task GetInviteAsync(string inviteId, RequestOptions options = null) => ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default); // IDiscordClient @@ -70,8 +70,8 @@ namespace Discord.WebSocket async Task> IDiscordClient.GetConnectionsAsync(RequestOptions options) => await GetConnectionsAsync(options).ConfigureAwait(false); - async Task IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options) - => await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false); + async Task IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options) + => await GetInviteAsync(inviteId, options).ConfigureAwait(false); Task IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(GetGuild(id)); diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs index 26d9363eb..e29cc4057 100644 --- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs +++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs @@ -328,8 +328,8 @@ namespace Discord.WebSocket async Task> IDiscordClient.GetConnectionsAsync(RequestOptions options) => await GetConnectionsAsync().ConfigureAwait(false); - async Task IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options) - => await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false); + async Task IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options) + => await GetInviteAsync(inviteId, options).ConfigureAwait(false); Task IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(GetGuild(id)); diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 412552d74..9efc7d3fa 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -1821,8 +1821,8 @@ namespace Discord.WebSocket async Task> IDiscordClient.GetConnectionsAsync(RequestOptions options) => await GetConnectionsAsync().ConfigureAwait(false); - async Task IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options) - => await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false); + async Task IDiscordClient.GetInviteAsync(string inviteId, RequestOptions options) + => await GetInviteAsync(inviteId, options).ConfigureAwait(false); Task IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(GetGuild(id)); From aadd6f639f7cdfa0abc9133eb279c88fa22144cf Mon Sep 17 00:00:00 2001 From: Finite Reality Date: Sat, 21 Jul 2018 01:07:29 +0100 Subject: [PATCH 06/12] Add missing fields to new MemberInfo type (#1107) --- .../AuditLogs/DataTypes/MemberInfo.cs | 18 +++++++++++ .../DataTypes/MemberUpdateAuditLogData.cs | 32 +++++++++++++------ 2 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs new file mode 100644 index 000000000..b0a1a8e5a --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs @@ -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; } + } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs index 38f078848..40a3ba681 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs @@ -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(); - var oldNick = changes.OldValue?.ToObject(); + 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(), + newNick = nickModel?.NewValue?.ToObject(); + bool? oldDeaf = deafModel?.OldValue?.ToObject(), + newDeaf = deafModel?.NewValue?.ToObject(); + bool? oldMute = muteModel?.OldValue?.ToObject(), + newMute = muteModel?.NewValue?.ToObject(); + string oldAvatar = avatarModel?.OldValue?.ToObject(), + newAvatar = avatarModel?.NewValue?.ToObject(); 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; } } } From afc3a9d0636598e6638a06781b86f48bac5c5376 Mon Sep 17 00:00:00 2001 From: Casino Boyale Date: Sat, 21 Jul 2018 01:31:30 +0100 Subject: [PATCH 07/12] Added GetJumpUrl() as an extension method for IMessage (#1102) * Added GetJumpUrl() as an IMessage extension method * Removed extra line for consistency * Moved the namespace from Discord.Commands to Discord * lint: remove eof newline * lint: use TextChannel to get GuildID --- .../Extensions/MessageExtensions.cs | 4 ++-- src/Discord.Net.Core/Extensions/MessageExtensions.cs | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/Discord.Net.Core/Extensions/MessageExtensions.cs diff --git a/src/Discord.Net.Commands/Extensions/MessageExtensions.cs b/src/Discord.Net.Commands/Extensions/MessageExtensions.cs index 096b03f6b..a27c5f322 100644 --- a/src/Discord.Net.Commands/Extensions/MessageExtensions.cs +++ b/src/Discord.Net.Commands/Extensions/MessageExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Discord.Commands { @@ -43,4 +43,4 @@ namespace Discord.Commands return false; } } -} \ No newline at end of file +} diff --git a/src/Discord.Net.Core/Extensions/MessageExtensions.cs b/src/Discord.Net.Core/Extensions/MessageExtensions.cs new file mode 100644 index 000000000..c53ef9053 --- /dev/null +++ b/src/Discord.Net.Core/Extensions/MessageExtensions.cs @@ -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}"; + } + } +} From 5dad0fa1a1f40c104cec86dde6d1c10a3025d915 Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Wed, 1 Aug 2018 16:10:21 +0200 Subject: [PATCH 08/12] Minor fixes around OnModuleBuilding (#1116) * Don't attempt instantiation of an abstract module * Attempt associating a TypeReader in case one is registered late (ie. OnModuleBuilding) --- .../Builders/ModuleBuilder.cs | 2 +- .../Builders/ParameterBuilder.cs | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs index 0ada5a9c2..6dc50db31 100644 --- a/src/Discord.Net.Commands/Builders/ModuleBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleBuilder.cs @@ -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(TypeInfo, service, services); moduleInstance.OnModuleBuilding(service, this); diff --git a/src/Discord.Net.Commands/Builders/ParameterBuilder.cs b/src/Discord.Net.Commands/Builders/ParameterBuilder.cs index d1782d7ea..8a59c247c 100644 --- a/src/Discord.Net.Commands/Builders/ParameterBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ParameterBuilder.cs @@ -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); } } -} \ No newline at end of file +} From c1d78189e11969c4ff9054bcd29323a3ffef7a54 Mon Sep 17 00:00:00 2001 From: Christopher F Date: Wed, 1 Aug 2018 15:09:46 -0400 Subject: [PATCH 09/12] core: add PrioritySpeaker to Permissions --- .../Entities/Permissions/ChannelPermission.cs | 3 ++- .../Entities/Permissions/ChannelPermissions.cs | 11 +++++++++-- .../Entities/Permissions/GuildPermission.cs | 1 + .../Entities/Permissions/GuildPermissions.cs | 11 +++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs b/src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs index 740b6c30b..0fbd22c4e 100644 --- a/src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs +++ b/src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs @@ -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, diff --git a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs index fa2dfb576..61d588f8a 100644 --- a/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs +++ b/src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs @@ -12,7 +12,7 @@ namespace Discord /// Gets a ChannelPermissions that grants all permissions for text channels. public static readonly ChannelPermissions Text = new ChannelPermissions(0b01100_0000000_1111111110001_010001); /// Gets a ChannelPermissions that grants all permissions for voice channels. - public static readonly ChannelPermissions Voice = new ChannelPermissions(0b00100_1111110_0000000010000_010001); + public static readonly ChannelPermissions Voice = new ChannelPermissions(0b00100_1111110_0000000010100_010001); /// Gets a ChannelPermissions that grants all permissions for category channels. public static readonly ChannelPermissions Category = new ChannelPermissions(0b01100_1111110_1111111110001_010001); /// Gets a ChannelPermissions that grants all permissions for direct message channels. @@ -78,6 +78,8 @@ namespace Discord public bool MoveMembers => Permissions.GetValue(RawValue, ChannelPermission.MoveMembers); /// If True, a user may use voice-activity-detection rather than push-to-talk. public bool UseVAD => Permissions.GetValue(RawValue, ChannelPermission.UseVAD); + /// If True, a user may use priority speaker in a voice channel. + public bool PrioritySpeaker => Permissions.GetValue(RawValue, ChannelPermission.PrioritySpeaker); /// If True, a user may adjust role permissions. This also implictly grants all other permissions. 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) { } /// Creates a new ChannelPermissions from this one, changing the provided non-null permissions. @@ -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); diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs index e90b4269e..13a9e32b1 100644 --- a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs +++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs @@ -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, diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs index 7704a62d6..c9cb90ec8 100644 --- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs +++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs @@ -12,7 +12,7 @@ namespace Discord /// Gets a GuildPermissions that grants all guild permissions for webhook users. public static readonly GuildPermissions Webhook = new GuildPermissions(0b00000_0000000_0001101100000_000000); /// Gets a GuildPermissions that grants all guild permissions. - public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_1111111110011_111111); + public static readonly GuildPermissions All = new GuildPermissions(0b11111_1111110_1111111110111_111111); /// Gets a packed value representing all the permissions in this GuildPermissions. public ulong RawValue { get; } @@ -69,6 +69,8 @@ namespace Discord public bool MoveMembers => Permissions.GetValue(RawValue, GuildPermission.MoveMembers); /// If True, a user may use voice-activity-detection rather than push-to-talk. public bool UseVAD => Permissions.GetValue(RawValue, GuildPermission.UseVAD); + /// If True, a user may use priority speaker in a voice channel. + public bool PrioritySpeaker => Permissions.GetValue(RawValue, ChannelPermission.PrioritySpeaker); /// If True, a user may change their own nickname. 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); From 2c3e9193c29c31a6822a24d7d574d6f827e95805 Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Thu, 9 Aug 2018 18:26:38 +0200 Subject: [PATCH 10/12] Implement ISnowflakeEntity for Audit Log entries --- src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs | 4 ++-- src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs index b85730a1d..150c59a42 100644 --- a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs +++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,7 +9,7 @@ namespace Discord /// /// Represents an entry in an audit log /// - public interface IAuditLogEntry : IEntity + public interface IAuditLogEntry : ISnowflakeEntity { /// /// The action which occured to create this entry diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs index 9e30a5014..d01e964ae 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs @@ -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); } + /// + public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); /// public ActionType Action { get; } /// From 748e92bcda7410f6a0891b33f15fd7b77fb93a24 Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Thu, 9 Aug 2018 02:20:36 +0200 Subject: [PATCH 11/12] Allow `FromError(Exception)` on all IResult types. --- src/Discord.Net.Commands/Results/ParseResult.cs | 5 ++++- src/Discord.Net.Commands/Results/PreconditionGroupResult.cs | 5 ++++- src/Discord.Net.Commands/Results/PreconditionResult.cs | 5 ++++- src/Discord.Net.Commands/Results/SearchResult.cs | 5 ++++- src/Discord.Net.Commands/Results/TypeReaderResult.cs | 2 ++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Discord.Net.Commands/Results/ParseResult.cs b/src/Discord.Net.Commands/Results/ParseResult.cs index d4a9af521..3a0692b2d 100644 --- a/src/Discord.Net.Commands/Results/ParseResult.cs +++ b/src/Discord.Net.Commands/Results/ParseResult.cs @@ -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); diff --git a/src/Discord.Net.Commands/Results/PreconditionGroupResult.cs b/src/Discord.Net.Commands/Results/PreconditionGroupResult.cs index 1d7f29122..ee650600a 100644 --- a/src/Discord.Net.Commands/Results/PreconditionGroupResult.cs +++ b/src/Discord.Net.Commands/Results/PreconditionGroupResult.cs @@ -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 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); diff --git a/src/Discord.Net.Commands/Results/PreconditionResult.cs b/src/Discord.Net.Commands/Results/PreconditionResult.cs index ca65a373e..01fc1a3fd 100644 --- a/src/Discord.Net.Commands/Results/PreconditionResult.cs +++ b/src/Discord.Net.Commands/Results/PreconditionResult.cs @@ -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); diff --git a/src/Discord.Net.Commands/Results/SearchResult.cs b/src/Discord.Net.Commands/Results/SearchResult.cs index 87d900d4d..6a5878ea2 100644 --- a/src/Discord.Net.Commands/Results/SearchResult.cs +++ b/src/Discord.Net.Commands/Results/SearchResult.cs @@ -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); diff --git a/src/Discord.Net.Commands/Results/TypeReaderResult.cs b/src/Discord.Net.Commands/Results/TypeReaderResult.cs index 639ca3ac1..e696dbc17 100644 --- a/src/Discord.Net.Commands/Results/TypeReaderResult.cs +++ b/src/Discord.Net.Commands/Results/TypeReaderResult.cs @@ -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); From db90eab9534967a9b4a43436991711a372aec320 Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Tue, 21 Aug 2018 06:27:50 +0800 Subject: [PATCH 12/12] Update README.md (#1117) * Initial commit * Add alternative suggestion * Fix typo * Update README.md --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index bd0ef20c7..7dc8cd788 100644 --- a/README.md +++ b/README.md @@ -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.