From 79811d0e618c011e6cca542811031d824650dae5 Mon Sep 17 00:00:00 2001 From: HelpfulStranger999 Date: Thu, 24 May 2018 17:35:38 -0500 Subject: [PATCH 01/11] Paginate reactions - solved #1007 (#1022) * Cleaned up and refactored slightly * Resolves #971 * Adds support for default avatars and resolves #971 * Amendment * Final amendment * Paginating reactions * Amendments based on feedback * Further amendment based on review * Final(?) amendment * Removes default limit and after user id * Removes fromUserId; cleans up model creation; replaces function with individual parameters --- src/Discord.Net.Core/DiscordConfig.cs | 3 +- .../Entities/Messages/IUserMessage.cs | 4 +- .../API/Rest/GetReactionUsersParams.cs | 2 +- src/Discord.Net.Rest/DiscordRestApiClient.cs | 4 +- .../Entities/Messages/MessageHelper.cs | 37 ++++++++++++++++--- .../Entities/Messages/RestUserMessage.cs | 4 +- .../Entities/Messages/SocketUserMessage.cs | 4 +- 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/Discord.Net.Core/DiscordConfig.cs b/src/Discord.Net.Core/DiscordConfig.cs index 1db3271e5..5cdf6a77e 100644 --- a/src/Discord.Net.Core/DiscordConfig.cs +++ b/src/Discord.Net.Core/DiscordConfig.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; namespace Discord { @@ -20,6 +20,7 @@ namespace Discord public const int MaxMessagesPerBatch = 100; public const int MaxUsersPerBatch = 1000; public const int MaxGuildsPerBatch = 100; + public const int MaxUserReactionsPerBatch = 100; public const int MaxAuditLogEntriesPerBatch = 100; /// Gets or sets how a request should act in the case of an error, by default. diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs index 52df187f8..36ee725ff 100644 --- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs +++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -23,7 +23,7 @@ namespace Discord /// Removes all reactions from this message. Task RemoveAllReactionsAsync(RequestOptions options = null); /// Gets all users that reacted to a message with a given emote - Task> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null); + IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null); /// Transforms this message's text into a human readable form by resolving its tags. string Resolve( diff --git a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs index d70da5632..a0967bb75 100644 --- a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs +++ b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs @@ -1,4 +1,4 @@ -namespace Discord.API.Rest +namespace Discord.API.Rest { internal class GetReactionUsersParams { diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 8b641fb6a..85e04f962 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -618,11 +618,11 @@ namespace Discord.API Preconditions.NotNullOrWhitespace(emoji, nameof(emoji)); Preconditions.NotNull(args, nameof(args)); Preconditions.GreaterThan(args.Limit, 0, nameof(args.Limit)); - Preconditions.AtMost(args.Limit, DiscordConfig.MaxUsersPerBatch, nameof(args.Limit)); + Preconditions.AtMost(args.Limit, DiscordConfig.MaxUserReactionsPerBatch, nameof(args.Limit)); Preconditions.GreaterThan(args.AfterUserId, 0, nameof(args.AfterUserId)); options = RequestOptions.CreateOrClone(options); - int limit = args.Limit.GetValueOrDefault(int.MaxValue); + int limit = args.Limit.GetValueOrDefault(DiscordConfig.MaxUserReactionsPerBatch); ulong afterUserId = args.AfterUserId.GetValueOrDefault(0); var ids = new BucketIds(channelId: channelId); diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs index 8ae41cc37..f7ce3ded0 100644 --- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs +++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs @@ -46,13 +46,38 @@ namespace Discord.Rest await client.ApiClient.RemoveAllReactionsAsync(msg.Channel.Id, msg.Id, options); } - public static async Task> GetReactionUsersAsync(IMessage msg, IEmote emote, - Action func, BaseDiscordClient client, RequestOptions options) + public static IAsyncEnumerable> GetReactionUsersAsync(IMessage msg, IEmote emote, + int? limit, BaseDiscordClient client, RequestOptions options) { - var args = new GetReactionUsersParams(); - func(args); - string emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name); - return (await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false)).Select(u => RestUser.Create(client, u)).ToImmutableArray(); + Preconditions.NotNull(emote, nameof(emote)); + var emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name); + + return new PagedAsyncEnumerable( + DiscordConfig.MaxUserReactionsPerBatch, + async (info, ct) => + { + var args = new GetReactionUsersParams + { + Limit = info.PageSize + }; + + if (info.Position != null) + args.AfterUserId = info.Position.Value; + + var models = await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false); + return models.Select(x => RestUser.Create(client, x)).ToImmutableArray(); + }, + nextPage: (info, lastPage) => + { + if (lastPage.Count != DiscordConfig.MaxUsersPerBatch) + return false; + + info.Position = lastPage.Max(x => x.Id); + return true; + }, + count: limit + ); + } public static async Task PinAsync(IMessage msg, BaseDiscordClient client, diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs index 0d1f3be2b..7354cc4af 100644 --- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs +++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs @@ -136,8 +136,8 @@ namespace Discord.Rest => MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options); public Task RemoveAllReactionsAsync(RequestOptions options = null) => MessageHelper.RemoveAllReactionsAsync(this, Discord, options); - public Task> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) - => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create(); }, Discord, options); + public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null) + => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options); public Task PinAsync(RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs index 5489ad2bb..f8c15a986 100644 --- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs +++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs @@ -130,8 +130,8 @@ namespace Discord.WebSocket => MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options); public Task RemoveAllReactionsAsync(RequestOptions options = null) => MessageHelper.RemoveAllReactionsAsync(this, Discord, options); - public Task> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) - => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create(); }, Discord, options); + public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null) + => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options); public Task PinAsync(RequestOptions options = null) => MessageHelper.PinAsync(this, Discord, options); From 0ba8b063ad98144232606f422574f9741fd95b7a Mon Sep 17 00:00:00 2001 From: HelpfulStranger999 Date: Thu, 24 May 2018 19:23:44 -0400 Subject: [PATCH 02/11] Makes text parameter of sending messages optional (#1042) commit 114e5b431b26669bcdaac9f84792a216ad67186f Author: HelpfulStranger999 Date: Sat Apr 28 19:08:35 2018 -0500 Fixes lack of default value for tts commit 1fd8c70c5346ff0c4fdb0093c0fc7fb4b3c8db2c Author: HelpfulStranger999 Date: Sat Apr 28 15:21:11 2018 -0500 Makes text parameter of sending messages optional --- src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs | 2 +- src/Discord.Net.Core/Extensions/UserExtensions.cs | 2 +- .../Entities/Channels/IRestMessageChannel.cs | 2 +- src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs | 2 +- src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs | 2 +- src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs | 2 +- .../Entities/Channels/RpcVirtualMessageChannel.cs | 6 +++--- .../Entities/Channels/ISocketMessageChannel.cs | 2 +- .../Entities/Channels/SocketDMChannel.cs | 2 +- .../Entities/Channels/SocketGroupChannel.cs | 2 +- .../Entities/Channels/SocketTextChannel.cs | 2 +- src/Discord.Net.Webhook/DiscordWebhookClient.cs | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs index 5a6e5df59..099b9da43 100644 --- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs @@ -8,7 +8,7 @@ namespace Discord public interface IMessageChannel : IChannel { /// Sends a message to this message channel. - Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); + Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); #if FILESYSTEM /// Sends a file to this text channel, with an optional caption. Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.Core/Extensions/UserExtensions.cs b/src/Discord.Net.Core/Extensions/UserExtensions.cs index d3e968e39..3296d00fd 100644 --- a/src/Discord.Net.Core/Extensions/UserExtensions.cs +++ b/src/Discord.Net.Core/Extensions/UserExtensions.cs @@ -9,7 +9,7 @@ namespace Discord /// Sends a message to the user via DM. /// public static async Task SendMessageAsync(this IUser user, - string text, + string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs index 8ab6e9819..b6f891f40 100644 --- a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs @@ -7,7 +7,7 @@ namespace Discord.Rest public interface IRestMessageChannel : IMessageChannel { /// Sends a message to this message channel. - new Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); + new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); #if FILESYSTEM /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs index 08acdf32b..f65ce79de 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs @@ -63,7 +63,7 @@ namespace Discord.Rest public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs index a1868573e..af9d80d84 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs @@ -76,7 +76,7 @@ namespace Discord.Rest public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 600b197d6..8a33ebd05 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -58,7 +58,7 @@ namespace Discord.Rest public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs index 3b6a68193..14cbc33f1 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs @@ -33,13 +33,13 @@ namespace Discord.Rest public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM - public Task SendFileAsync(string filePath, string text, bool isTTS, Embed embed = null, RequestOptions options = null) + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); #endif - public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed = null, RequestOptions options = null) + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); public Task TriggerTypingAsync(RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs index 026bd8378..971dbe8f1 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs @@ -11,7 +11,7 @@ namespace Discord.WebSocket IReadOnlyCollection CachedMessages { get; } /// Sends a message to this message channel. - new Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); + new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); #if FILESYSTEM /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs index 451240e66..764431ae1 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs @@ -67,7 +67,7 @@ namespace Discord.WebSocket public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs index d46c5fc59..1d68109ee 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs @@ -95,7 +95,7 @@ namespace Discord.WebSocket public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index ec7615b55..f776c9956 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -75,7 +75,7 @@ namespace Discord.WebSocket public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); - public Task SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) diff --git a/src/Discord.Net.Webhook/DiscordWebhookClient.cs b/src/Discord.Net.Webhook/DiscordWebhookClient.cs index 59cc8f3e7..2dea1c1d1 100644 --- a/src/Discord.Net.Webhook/DiscordWebhookClient.cs +++ b/src/Discord.Net.Webhook/DiscordWebhookClient.cs @@ -63,7 +63,7 @@ namespace Discord.Webhook => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent); /// Sends a message using to the channel for this webhook. Returns the ID of the created message. - public Task SendMessageAsync(string text, bool isTTS = false, IEnumerable embeds = null, + public Task SendMessageAsync(string text = null, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendMessageAsync(this, text, isTTS, embeds, username, avatarUrl, options); From bf5275e071b78a25fd4501a930e69c5dc8cd3b19 Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Thu, 24 May 2018 19:36:00 -0400 Subject: [PATCH 03/11] Add ability to specify parameters on channel creation (#1020) commit 07bca5b31a3580d55278878eabb56a82973f8c8f Author: Joe4evr Date: Fri Apr 6 09:44:50 2018 +0200 Add ability to specify parameters on channel creation --- .../Entities/Guilds/IGuild.cs | 4 ++-- .../API/Rest/CreateGuildChannelParams.cs | 13 +++++++++- .../Entities/Guilds/GuildHelper.cs | 24 +++++++++++++++---- .../Entities/Guilds/RestGuild.cs | 16 ++++++------- .../Entities/Guilds/SocketGuild.cs | 16 ++++++------- 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index 19d2ee81c..f6e13e0e1 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -109,9 +109,9 @@ namespace Discord Task GetDefaultChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); /// Creates a new text channel. - Task CreateTextChannelAsync(string name, RequestOptions options = null); + Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null); /// Creates a new voice channel. - Task CreateVoiceChannelAsync(string name, RequestOptions options = null); + Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null); /// Creates a new channel category. Task CreateCategoryAsync(string name, RequestOptions options = null); diff --git a/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs b/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs index bae677148..05cdf4b8a 100644 --- a/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs +++ b/src/Discord.Net.Rest/API/Rest/CreateGuildChannelParams.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using Newtonsoft.Json; namespace Discord.API.Rest @@ -10,9 +10,20 @@ namespace Discord.API.Rest public string Name { get; } [JsonProperty("type")] public ChannelType Type { get; } + [JsonProperty("parent_id")] + public Optional CategoryId { get; set; } + //Text channels + [JsonProperty("topic")] + public Optional Topic { get; set; } + [JsonProperty("nsfw")] + public Optional IsNsfw { get; set; } + + //Voice channels [JsonProperty("bitrate")] public Optional Bitrate { get; set; } + [JsonProperty("user_limit")] + public Optional UserLimit { get; set; } public CreateGuildChannelParams(string name, ChannelType type) { diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index 6ccb02f93..c76b41a91 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -145,20 +145,36 @@ namespace Discord.Rest return models.Select(x => RestGuildChannel.Create(client, guild, x)).ToImmutableArray(); } public static async Task CreateTextChannelAsync(IGuild guild, BaseDiscordClient client, - string name, RequestOptions options) + string name, RequestOptions options, Action func = null) { if (name == null) throw new ArgumentNullException(nameof(name)); - var args = new CreateGuildChannelParams(name, ChannelType.Text); + var props = new TextChannelProperties(); + func?.Invoke(props); + + var args = new CreateGuildChannelParams(name, ChannelType.Text) + { + CategoryId = props.CategoryId, + Topic = props.Topic, + IsNsfw = props.IsNsfw + }; var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); return RestTextChannel.Create(client, guild, model); } public static async Task CreateVoiceChannelAsync(IGuild guild, BaseDiscordClient client, - string name, RequestOptions options) + string name, RequestOptions options, Action func = null) { if (name == null) throw new ArgumentNullException(nameof(name)); - var args = new CreateGuildChannelParams(name, ChannelType.Voice); + var props = new VoiceChannelProperties(); + func?.Invoke(props); + + var args = new CreateGuildChannelParams(name, ChannelType.Voice) + { + CategoryId = props.CategoryId, + Bitrate = props.Bitrate, + UserLimit = props.UserLimit + }; var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); return RestVoiceChannel.Create(client, guild, model); } diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 8d1937953..91b548be4 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -222,10 +222,10 @@ namespace Discord.Rest } return null; } - public Task CreateTextChannelAsync(string name, RequestOptions options = null) - => GuildHelper.CreateTextChannelAsync(this, Discord, name, options); - public Task CreateVoiceChannelAsync(string name, RequestOptions options = null) - => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options); + public Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null) + => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func); + public Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null) + => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); public Task CreateCategoryChannelAsync(string name, RequestOptions options = null) => GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options); @@ -383,10 +383,10 @@ namespace Discord.Rest else return null; } - async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options) - => await CreateTextChannelAsync(name, options).ConfigureAwait(false); - async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options) - => await CreateVoiceChannelAsync(name, options).ConfigureAwait(false); + async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options, Action func) + => await CreateTextChannelAsync(name, options, func).ConfigureAwait(false); + async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options, Action func) + => await CreateVoiceChannelAsync(name, options, func).ConfigureAwait(false); async Task IGuild.CreateCategoryAsync(string name, RequestOptions options) => await CreateCategoryChannelAsync(name, options).ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index e332fcd9a..a6ef1925b 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -315,10 +315,10 @@ namespace Discord.WebSocket => GetChannel(id) as SocketTextChannel; public SocketVoiceChannel GetVoiceChannel(ulong id) => GetChannel(id) as SocketVoiceChannel; - public Task CreateTextChannelAsync(string name, RequestOptions options = null) - => GuildHelper.CreateTextChannelAsync(this, Discord, name, options); - public Task CreateVoiceChannelAsync(string name, RequestOptions options = null) - => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options); + public Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null) + => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func); + public Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null) + => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); public Task CreateCategoryChannelAsync(string name, RequestOptions options = null) => GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options); @@ -678,10 +678,10 @@ namespace Discord.WebSocket => Task.FromResult(EmbedChannel); Task IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) => Task.FromResult(SystemChannel); - async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options) - => await CreateTextChannelAsync(name, options).ConfigureAwait(false); - async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options) - => await CreateVoiceChannelAsync(name, options).ConfigureAwait(false); + async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options, Action func) + => await CreateTextChannelAsync(name, options, func).ConfigureAwait(false); + async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options, Action func) + => await CreateVoiceChannelAsync(name, options, func).ConfigureAwait(false); async Task IGuild.CreateCategoryAsync(string name, RequestOptions options) => await CreateCategoryChannelAsync(name, options).ConfigureAwait(false); From 5023357a60bd5ae454b35426ddd279fb3284b7e8 Mon Sep 17 00:00:00 2001 From: Christopher F Date: Thu, 24 May 2018 19:36:33 -0400 Subject: [PATCH 04/11] codefix #1020: RequestOptions should always be sorted last --- src/Discord.Net.Core/Entities/Guilds/IGuild.cs | 4 ++-- src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs | 12 ++++++------ .../Entities/Guilds/SocketGuild.cs | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index f6e13e0e1..4c1c274d0 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -109,9 +109,9 @@ namespace Discord Task GetDefaultChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); /// Creates a new text channel. - Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null); + Task CreateTextChannelAsync(string name, Action func = null, RequestOptions options = null); /// Creates a new voice channel. - Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null); + Task CreateVoiceChannelAsync(string name, Action func = null, RequestOptions options = null); /// Creates a new channel category. Task CreateCategoryAsync(string name, RequestOptions options = null); diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 91b548be4..357e22c85 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -222,9 +222,9 @@ namespace Discord.Rest } return null; } - public Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null) + public Task CreateTextChannelAsync(string name, Action func = null, RequestOptions options = null) => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func); - public Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null) + public Task CreateVoiceChannelAsync(string name, Action func = null, RequestOptions options = null) => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); public Task CreateCategoryChannelAsync(string name, RequestOptions options = null) => GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options); @@ -383,10 +383,10 @@ namespace Discord.Rest else return null; } - async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options, Action func) - => await CreateTextChannelAsync(name, options, func).ConfigureAwait(false); - async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options, Action func) - => await CreateVoiceChannelAsync(name, options, func).ConfigureAwait(false); + async Task IGuild.CreateTextChannelAsync(string name, Action func, RequestOptions options) + => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); + async Task IGuild.CreateVoiceChannelAsync(string name, Action func, RequestOptions options) + => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false); async Task IGuild.CreateCategoryAsync(string name, RequestOptions options) => await CreateCategoryChannelAsync(name, options).ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index a6ef1925b..14263f0af 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -315,9 +315,9 @@ namespace Discord.WebSocket => GetChannel(id) as SocketTextChannel; public SocketVoiceChannel GetVoiceChannel(ulong id) => GetChannel(id) as SocketVoiceChannel; - public Task CreateTextChannelAsync(string name, RequestOptions options = null, Action func = null) + public Task CreateTextChannelAsync(string name, Action func = null, RequestOptions options = null) => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func); - public Task CreateVoiceChannelAsync(string name, RequestOptions options = null, Action func = null) + public Task CreateVoiceChannelAsync(string name, Action func = null, RequestOptions options = null) => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); public Task CreateCategoryChannelAsync(string name, RequestOptions options = null) => GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options); @@ -678,10 +678,10 @@ namespace Discord.WebSocket => Task.FromResult(EmbedChannel); Task IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) => Task.FromResult(SystemChannel); - async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options, Action func) - => await CreateTextChannelAsync(name, options, func).ConfigureAwait(false); - async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options, Action func) - => await CreateVoiceChannelAsync(name, options, func).ConfigureAwait(false); + async Task IGuild.CreateTextChannelAsync(string name, Action func, RequestOptions options) + => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); + async Task IGuild.CreateVoiceChannelAsync(string name, Action func, RequestOptions options) + => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false); async Task IGuild.CreateCategoryAsync(string name, RequestOptions options) => await CreateCategoryChannelAsync(name, options).ConfigureAwait(false); From c275e575289073fe42ead725de97b97301c7dc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?o=20Acid=20Chicken=20=28=E7=A1=AB=E7=A1=AB=E2=96=92=7EE?= =?UTF-8?q?=E2=96=92=E2=96=92=E2=96=92=7EO=29?= Date: Thu, 24 May 2018 19:52:25 -0400 Subject: [PATCH 05/11] Add support casting System.Drawing.Color to Discord.Color MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fa3303426766a59e7aa4d67e8b50826cfe7204ec Author: Acid Chicken (硫酸鶏) Date: Sun Apr 29 13:50:56 2018 +0900 Use built-in symbol refs: https://github.com/RogueException/Discord.Net/pull/1043#issuecomment-385223999 commit 27ea82668587960925b73f97c924c9d39ee71f7b Author: Acid Chicken (硫酸鶏) Date: Sun Apr 29 11:29:31 2018 +0900 Add support casting System.Drawing.Color to Discord.Color commit 1ab9de24978ff24a018767f80dc95ba19b616988 Merge: f5bb99c7 a4d1e2bc Author: Acid Chicken (硫酸鶏) Date: Sun Apr 29 10:16:46 2018 +0900 Merge remote-tracking branch 'upstream/dev' into dev commit f5bb99c77d0fecec21ad769778d17144c047d8b1 Merge: 3be8e40d b8b59d97 Author: Acid Chicken (硫酸鶏) Date: Tue Apr 10 11:07:36 2018 +0900 Merge remote-tracking branch 'upstream/dev' into dev commit 3be8e40d3814fe8455af475b8641ee07a8f368d6 Merge: c692306f 9d77a3cd Author: Acid Chicken (硫酸鶏) Date: Sun Jan 7 15:05:31 2018 +0900 Merge remote-tracking branch 'upstream/dev' into dev commit c692306fcc1e86ab92dd10683d3719f16c02a249 Author: Acid Chicken (硫酸鶏) Date: Sat Nov 11 10:49:00 2017 +0900 Add target of the internal fields commit 2d08f9a655b4949c1177f778d0f499047484a537 Author: Acid Chicken (硫酸鶏) Date: Sat Nov 11 10:17:42 2017 +0900 Add some more extension commit 4f19b835ffe8c64a93a9b4659e60b03ac797760f Author: Acid Chicken (硫酸鶏) Date: Sat Nov 11 01:19:11 2017 +0900 Add naming rules commit af756cd9feb630baadbf6025cbb079cd9e1f45cb Author: Acid Chicken (硫酸鶏) Date: Sat Nov 11 00:35:30 2017 +0900 Add basic .NET style rules commit 503ece558b4f07bd8008157d3aeb6a4e7100d349 Author: Acid Chicken (硫酸鶏) Date: Fri Nov 10 22:36:52 2017 +0900 Add EditorConfig --- src/Discord.Net.Core/Discord.Net.Core.csproj | 4 ++-- src/Discord.Net.Core/Entities/Roles/Color.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj index 7565fa178..321803114 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.csproj +++ b/src/Discord.Net.Core/Discord.Net.Core.csproj @@ -4,8 +4,8 @@ Discord.Net.Core Discord The core components for the Discord.Net library. - net45;netstandard1.1;netstandard1.3 - netstandard1.1;netstandard1.3 + net45;netstandard1.1;netstandard1.3;netstandard2.0 + netstandard1.1;netstandard1.3;netstandard2.0 diff --git a/src/Discord.Net.Core/Entities/Roles/Color.cs b/src/Discord.Net.Core/Entities/Roles/Color.cs index 89e76df6d..0bb04d339 100644 --- a/src/Discord.Net.Core/Entities/Roles/Color.cs +++ b/src/Discord.Net.Core/Entities/Roles/Color.cs @@ -1,5 +1,8 @@ using System; using System.Diagnostics; +#if NETSTANDARD2_0 || NET45 +using StandardColor = System.Drawing.Color; +#endif namespace Discord { @@ -96,7 +99,14 @@ namespace Discord ((uint)(g * 255.0f) << 8) | (uint)(b * 255.0f); } - + +#if NETSTANDARD2_0 || NET45 + public static implicit operator StandardColor(Color color) => + StandardColor.FromArgb((int)color.RawValue); + public static explicit operator Color(StandardColor color) => + new Color((uint)color.ToArgb() << 8 >> 8); +#endif + public override string ToString() => $"#{Convert.ToString(RawValue, 16)}"; private string DebuggerDisplay => From b52af7ae7caaddd79101aeb9f5af2ce482890bc2 Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Fri, 25 May 2018 01:59:32 +0200 Subject: [PATCH 06/11] Add a dedicated TimeSpan reader so it doesn't suck (#1005) * Add a dedicated TimeSpan reader so it doesn't suck * Pass input as lower case --- src/Discord.Net.Commands/CommandService.cs | 4 +++ src/Discord.Net.Commands/PrimitiveParsers.cs | 4 +-- .../Readers/TimeSpanTypeReader.cs | 35 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index c996f7334..b20c231c3 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -65,6 +65,10 @@ namespace Discord.Commands _defaultTypeReaders[typeof(Nullable<>).MakeGenericType(type)] = NullableTypeReader.Create(type, _defaultTypeReaders[type]); } + var tsreader = new TimeSpanTypeReader(); + _defaultTypeReaders[typeof(TimeSpan)] = tsreader; + _defaultTypeReaders[typeof(TimeSpan?)] = NullableTypeReader.Create(typeof(TimeSpan), tsreader); + _defaultTypeReaders[typeof(string)] = new PrimitiveTypeReader((string x, out string y) => { y = x; return true; }, 0); diff --git a/src/Discord.Net.Commands/PrimitiveParsers.cs b/src/Discord.Net.Commands/PrimitiveParsers.cs index 6a54ba402..bf0622c28 100644 --- a/src/Discord.Net.Commands/PrimitiveParsers.cs +++ b/src/Discord.Net.Commands/PrimitiveParsers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -29,7 +29,7 @@ namespace Discord.Commands parserBuilder[typeof(decimal)] = (TryParseDelegate)decimal.TryParse; parserBuilder[typeof(DateTime)] = (TryParseDelegate)DateTime.TryParse; parserBuilder[typeof(DateTimeOffset)] = (TryParseDelegate)DateTimeOffset.TryParse; - parserBuilder[typeof(TimeSpan)] = (TryParseDelegate)TimeSpan.TryParse; + //parserBuilder[typeof(TimeSpan)] = (TryParseDelegate)TimeSpan.TryParse; parserBuilder[typeof(char)] = (TryParseDelegate)char.TryParse; return parserBuilder.ToImmutable(); } diff --git a/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs b/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs new file mode 100644 index 000000000..31ab9d821 --- /dev/null +++ b/src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs @@ -0,0 +1,35 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + internal class TimeSpanTypeReader : TypeReader + { + private static readonly string[] _formats = new[] + { + "%d'd'%h'h'%m'm'%s's'", //4d3h2m1s + "%d'd'%h'h'%m'm'", //4d3h2m + "%d'd'%h'h'%s's'", //4d3h 1s + "%d'd'%h'h'", //4d3h + "%d'd'%m'm'%s's'", //4d 2m1s + "%d'd'%m'm'", //4d 2m + "%d'd'%s's'", //4d 1s + "%d'd'", //4d + "%h'h'%m'm'%s's'", // 3h2m1s + "%h'h'%m'm'", // 3h2m + "%h'h'%s's'", // 3h 1s + "%h'h'", // 3h + "%m'm'%s's'", // 2m1s + "%m'm'", // 2m + "%s's'", // 1s + }; + + public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + { + return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan)) + ? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan)) + : Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan")); + } + } +} From cee71ef35a450802ef35090d9eaf167ca39306e8 Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Thu, 24 May 2018 17:07:37 -0700 Subject: [PATCH 07/11] Add support for parsing multiple types of quotation marks in commands, Fix #942 (#943) * Add ability to support different types of quotation marks * Added normal quotation mark to list of aliases, removed single quote mark * clean up leftover changes from testing * change quotation mark parsing to use a map of matching pairs * remove commented out code * Fix conventions of the command parser utility functions * change storage type of alias dictionary to be IReadOnlyDictionary * revert type of CommandServiceConfig QuotationMarkAliasMap to Dictionary * minor formatting changes to CommandParser * remove unnecessary whitespace * Move aliases outside of CommandInfo class * copy IReadOnlyDictionary to ImmutableDictionary * minor syntax changes in CommandServiceConfig * add newline before namespace for consistency * newline formatting tweak * simplification of GetMatch method for CommandParser * add more quote unicode punctuation pairs * add check for null value when building ImmutableDictionary * Move default alias map into a separate source file * Ensure that the collection passed into command service is not null --- src/Discord.Net.Commands/CommandParser.cs | 34 +++++-- src/Discord.Net.Commands/CommandService.cs | 5 +- .../CommandServiceConfig.cs | 5 + src/Discord.Net.Commands/Info/CommandInfo.cs | 5 +- .../Utilities/QuotationAliasUtils.cs | 95 +++++++++++++++++++ 5 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index 64daf841e..9ce4e1469 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Text; using System.Threading.Tasks; @@ -13,8 +14,7 @@ namespace Discord.Commands Parameter, QuotedParameter } - - public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos) + public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, bool ignoreExtraArgs, IServiceProvider services, string input, int startPos, IReadOnlyDictionary aliasMap) { ParameterInfo curParam = null; StringBuilder argBuilder = new StringBuilder(input.Length); @@ -24,7 +24,27 @@ namespace Discord.Commands var argList = ImmutableArray.CreateBuilder(); var paramList = ImmutableArray.CreateBuilder(); bool isEscaping = false; - char c; + char c, matchQuote = '\0'; + + // local helper functions + bool IsOpenQuote(IReadOnlyDictionary dict, char ch) + { + // return if the key is contained in the dictionary if it is populated + if (dict.Count != 0) + return dict.ContainsKey(ch); + // or otherwise if it is the default double quote + return c == '\"'; + } + + char GetMatch(IReadOnlyDictionary dict, char ch) + { + // get the corresponding value for the key, if it exists + // and if the dictionary is populated + if (dict.Count != 0 && dict.TryGetValue(c, out var value)) + return value; + // or get the default pair of the default double quote + return '\"'; + } for (int curPos = startPos; curPos <= endPos; curPos++) { @@ -74,9 +94,11 @@ namespace Discord.Commands argBuilder.Append(c); continue; } - if (c == '\"') + + if (IsOpenQuote(aliasMap, c)) { curPart = ParserPart.QuotedParameter; + matchQuote = GetMatch(aliasMap, c); continue; } curPart = ParserPart.Parameter; @@ -97,7 +119,7 @@ namespace Discord.Commands } else if (curPart == ParserPart.QuotedParameter) { - if (c == '\"') + if (c == matchQuote) { argString = argBuilder.ToString(); //Remove quotes lastArgEndPos = curPos + 1; diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index b20c231c3..f75653ccf 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; @@ -32,6 +32,7 @@ namespace Discord.Commands internal readonly RunMode _defaultRunMode; internal readonly Logger _cmdLogger; internal readonly LogManager _logManager; + internal readonly IReadOnlyDictionary _quotationMarkAliasMap; public IEnumerable Modules => _moduleDefs.Select(x => x); public IEnumerable Commands => _moduleDefs.SelectMany(x => x.Commands); @@ -45,6 +46,7 @@ namespace Discord.Commands _ignoreExtraArgs = config.IgnoreExtraArgs; _separatorChar = config.SeparatorChar; _defaultRunMode = config.DefaultRunMode; + _quotationMarkAliasMap = (config.QuotationMarkAliasMap ?? new Dictionary()).ToImmutableDictionary(); if (_defaultRunMode == RunMode.Default) throw new InvalidOperationException("The default run mode cannot be set to Default."); @@ -337,7 +339,6 @@ namespace Discord.Commands public async Task ExecuteAsync(ICommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { services = services ?? EmptyServiceProvider.Instance; - var searchResult = Search(context, input); if (!searchResult.IsSuccess) return searchResult; diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs index f5cd14fef..00091634d 100644 --- a/src/Discord.Net.Commands/CommandServiceConfig.cs +++ b/src/Discord.Net.Commands/CommandServiceConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Discord.Commands { @@ -18,6 +19,10 @@ namespace Discord.Commands /// Determines whether RunMode.Sync commands should push exceptions up to the caller. public bool ThrowOnError { get; set; } = true; + /// Collection of aliases that can wrap strings for command parsing. + /// represents the opening quotation mark and the value is the corresponding closing mark. + public Dictionary QuotationMarkAliasMap { get; set; } = QuotationAliasUtils.GetDefaultAliasMap; + /// Determines whether extra parameters should be ignored. public bool IgnoreExtraArgs { get; set; } = false; } diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index 1a9cf69c5..df0bb297b 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -1,4 +1,4 @@ -using Discord.Commands.Builders; +using Discord.Commands.Builders; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -121,7 +121,8 @@ namespace Discord.Commands return ParseResult.FromError(preconditionResult); string input = searchResult.Text.Substring(startIndex); - return await CommandParser.ParseArgsAsync(this, context, services, input, 0).ConfigureAwait(false); + + return await CommandParser.ParseArgsAsync(this, context, _commandService._ignoreExtraArgs, services, input, 0, _commandService._quotationMarkAliasMap).ConfigureAwait(false); } public Task ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) diff --git a/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs b/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs new file mode 100644 index 000000000..15a08b9b3 --- /dev/null +++ b/src/Discord.Net.Commands/Utilities/QuotationAliasUtils.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Globalization; + +namespace Discord.Commands +{ + /// + /// Utility methods for generating matching pairs of unicode quotation marks for CommandServiceConfig + /// + internal static class QuotationAliasUtils + { + /// + /// Generates an IEnumerable of characters representing open-close pairs of + /// quotation punctuation. + /// + internal static Dictionary GetDefaultAliasMap + { + get + { + // Output of a gist provided by https://gist.github.com/ufcpp + // https://gist.github.com/ufcpp/5b2cf9a9bf7d0b8743714a0b88f7edc5 + // This was not used for the implementation because of incompatibility with netstandard1.1 + return new Dictionary { + {'\"', '\"' }, + {'«', '»' }, + {'‘', '’' }, + {'“', '”' }, + {'„', '‟' }, + {'‹', '›' }, + {'‚', '‛' }, + {'《', '》' }, + {'〈', '〉' }, + {'「', '」' }, + {'『', '』' }, + {'〝', '〞' }, + {'﹁', '﹂' }, + {'﹃', '﹄' }, + {'"', '"' }, + {''', ''' }, + {'「', '」' }, + {'(', ')' }, + {'༺', '༻' }, + {'༼', '༽' }, + {'᚛', '᚜' }, + {'⁅', '⁆' }, + {'⌈', '⌉' }, + {'⌊', '⌋' }, + {'❨', '❩' }, + {'❪', '❫' }, + {'❬', '❭' }, + {'❮', '❯' }, + {'❰', '❱' }, + {'❲', '❳' }, + {'❴', '❵' }, + {'⟅', '⟆' }, + {'⟦', '⟧' }, + {'⟨', '⟩' }, + {'⟪', '⟫' }, + {'⟬', '⟭' }, + {'⟮', '⟯' }, + {'⦃', '⦄' }, + {'⦅', '⦆' }, + {'⦇', '⦈' }, + {'⦉', '⦊' }, + {'⦋', '⦌' }, + {'⦍', '⦎' }, + {'⦏', '⦐' }, + {'⦑', '⦒' }, + {'⦓', '⦔' }, + {'⦕', '⦖' }, + {'⦗', '⦘' }, + {'⧘', '⧙' }, + {'⧚', '⧛' }, + {'⧼', '⧽' }, + {'⸂', '⸃' }, + {'⸄', '⸅' }, + {'⸉', '⸊' }, + {'⸌', '⸍' }, + {'⸜', '⸝' }, + {'⸠', '⸡' }, + {'⸢', '⸣' }, + {'⸤', '⸥' }, + {'⸦', '⸧' }, + {'⸨', '⸩' }, + {'【', '】'}, + {'〔', '〕' }, + {'〖', '〗' }, + {'〘', '〙' }, + {'〚', '〛' } + }; + } + } + } +} From bc6009ec7207e16aedecdc658dc59b8ac02c400e Mon Sep 17 00:00:00 2001 From: Still Hsu <341464@gmail.com> Date: Fri, 25 May 2018 08:08:51 +0800 Subject: [PATCH 08/11] Implement IMessageChannel#DeleteMessageAsync (#996) * Implement DeleteMessageAsync * Refer to MessageHelper instead of duplicating call * Fix refactor error --- src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs | 5 +++++ src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs | 4 ++++ src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs | 5 +++++ src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs | 5 +++++ src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs | 5 +++++ .../Entities/Channels/RpcVirtualMessageChannel.cs | 5 +++++ src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs | 6 ++++-- .../Entities/Channels/SocketDMChannel.cs | 5 +++++ .../Entities/Channels/SocketGroupChannel.cs | 5 +++++ .../Entities/Channels/SocketTextChannel.cs | 5 +++++ 10 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs index 099b9da43..262b865ea 100644 --- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs @@ -30,6 +30,11 @@ namespace Discord /// Gets a collection of pinned messages in this channel. Task> GetPinnedMessagesAsync(RequestOptions options = null); + /// Deletes a message based on the message ID in this channel. + Task DeleteMessageAsync(ulong messageId, RequestOptions options = null); + /// Deletes a message based on the provided message in this channel. + Task DeleteMessageAsync(IMessage message, RequestOptions options = null); + /// Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds. Task TriggerTypingAsync(RequestOptions options = null); /// Continuously broadcasts the "user is typing" message to all users in this channel until the returned object is disposed. diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs index 6784f7f6a..dbbabbd72 100644 --- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs +++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs @@ -185,6 +185,10 @@ namespace Discord.Rest return RestUserMessage.Create(client, channel, client.CurrentUser, model); } + public static Task DeleteMessageAsync(IMessageChannel channel, ulong messageId, BaseDiscordClient client, + RequestOptions options) + => MessageHelper.DeleteAsync(channel.Id, messageId, client, options); + public static async Task DeleteMessagesAsync(ITextChannel channel, BaseDiscordClient client, IEnumerable messageIds, RequestOptions options) { diff --git a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs index f65ce79de..21cd579e6 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs @@ -72,6 +72,11 @@ namespace Discord.Rest public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); public IDisposable EnterTypingState(RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs index af9d80d84..901016a6b 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs @@ -76,6 +76,11 @@ namespace Discord.Rest public Task> GetPinnedMessagesAsync(RequestOptions options = null) => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); #if FILESYSTEM diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 8a33ebd05..841aad666 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -67,6 +67,11 @@ namespace Discord.Rest public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options); public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs index 14cbc33f1..8f69388d4 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs @@ -42,6 +42,11 @@ namespace Discord.Rest public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); public IDisposable EnterTypingState(RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs index f7ce3ded0..3dc3e74e9 100644 --- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs +++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs @@ -25,10 +25,12 @@ namespace Discord.Rest }; return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false); } - public static async Task DeleteAsync(IMessage msg, BaseDiscordClient client, + public static Task DeleteAsync(IMessage msg, BaseDiscordClient client, RequestOptions options) + => DeleteAsync(msg.Channel.Id, msg.Id, client, options); + public static async Task DeleteAsync(ulong channelId, ulong msgId, BaseDiscordClient client, RequestOptions options) { - await client.ApiClient.DeleteMessageAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false); + await client.ApiClient.DeleteMessageAsync(channelId, msgId, options).ConfigureAwait(false); } public static async Task AddReactionAsync(IMessage msg, IEmote emote, BaseDiscordClient client, RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs index 764431ae1..d95d45890 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs @@ -76,6 +76,11 @@ namespace Discord.WebSocket public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); public IDisposable EnterTypingState(RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs index 1d68109ee..3d6f60db2 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs @@ -104,6 +104,11 @@ namespace Discord.WebSocket public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); public IDisposable EnterTypingState(RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index f776c9956..9373c431a 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -89,6 +89,11 @@ namespace Discord.WebSocket public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) => ChannelHelper.DeleteMessagesAsync(this, Discord, messageIds, options); + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options); + public Task TriggerTypingAsync(RequestOptions options = null) => ChannelHelper.TriggerTypingAsync(this, Discord, options); public IDisposable EnterTypingState(RequestOptions options = null) From 5f084adf94f3215b6d68c3a8b61cbfad7376f18c Mon Sep 17 00:00:00 2001 From: HelpfulStranger999 Date: Thu, 24 May 2018 19:17:19 -0500 Subject: [PATCH 09/11] Deprecates ReadMessages, introduces ViewChannel (#1033) * Deprecates ReadMessages, introduces ViewChannel * Adds period and comma somehow missed --- .../Entities/Permissions/GuildPermission.cs | 6 ++++-- .../Entities/Permissions/GuildPermissions.cs | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs index 8469fd304..e90b4269e 100644 --- a/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs +++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermission.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Discord { @@ -16,7 +16,9 @@ namespace Discord // Text AddReactions = 0x00_00_00_40, ViewAuditLog = 0x00_00_00_80, - ReadMessages = 0x00_00_04_00, + [Obsolete("Use ViewChannel instead.")] + ReadMessages = ViewChannel, + ViewChannel = 0x00_00_04_00, SendMessages = 0x00_00_08_00, SendTTSMessages = 0x00_00_10_00, ManageMessages = 0x00_00_20_00, diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs index a880e62ca..dcebeb20d 100644 --- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs +++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics; namespace Discord @@ -35,7 +36,10 @@ namespace Discord public bool ViewAuditLog => Permissions.GetValue(RawValue, GuildPermission.ViewAuditLog); /// If True, a user may join channels. - public bool ReadMessages => Permissions.GetValue(RawValue, GuildPermission.ReadMessages); + [Obsolete("Use ViewChannel instead.")] + public bool ReadMessages => ViewChannel; + /// If True, a user may view channels. + public bool ViewChannel => Permissions.GetValue(RawValue, GuildPermission.ViewChannel); /// If True, a user may send messages. public bool SendMessages => Permissions.GetValue(RawValue, GuildPermission.SendMessages); /// If True, a user may send text-to-speech messages. From bbbac85c46162d7bb44ecdd68194ab79db25037d Mon Sep 17 00:00:00 2001 From: Hawx Date: Fri, 25 May 2018 20:14:28 +0800 Subject: [PATCH 10/11] Update Dependencies and support NS2.0 builds (#1046) * Update deps, fix test warnings. * Support ns2.0 * Fix typo * Remove ns1.1 support * Net.Http and Net.Websockets.Client are not needed in ns2.0 * Move to net46 per volt * Remove ns1.3 constants --- Discord.Net.targets | 8 +-- .../02_commands_framework.csproj | 2 +- .../Discord.Net.Analyzers.csproj | 2 +- .../Discord.Net.Commands.csproj | 10 ++-- src/Discord.Net.Core/Discord.Net.Core.csproj | 10 ++-- .../Entities/Channels/IMessageChannel.cs | 3 +- src/Discord.Net.Core/Entities/Image.cs | 6 +-- .../Extensions/UserExtensions.cs | 2 - src/Discord.Net.Core/Logging/LogManager.cs | 23 ++++---- src/Discord.Net.Core/Logging/Logger.cs | 25 +++++---- src/Discord.Net.Core/Utils/DateTimeUtils.cs | 47 +---------------- src/Discord.Net.Core/Utils/SnowflakeUtils.cs | 4 +- src/Discord.Net.Rest/Discord.Net.Rest.csproj | 13 +++-- .../Entities/Channels/ChannelHelper.cs | 3 +- .../Entities/Channels/IRestMessageChannel.cs | 3 +- .../Entities/Channels/RestDMChannel.cs | 7 ++- .../Entities/Channels/RestGroupChannel.cs | 7 ++- .../Entities/Channels/RestTextChannel.cs | 7 ++- .../Channels/RpcVirtualMessageChannel.cs | 6 +-- .../Net/Converters/DiscordContractResolver.cs | 3 +- .../Net/Queue/RequestQueueBucket.cs | 2 +- src/Discord.Net.Rest/Net/RateLimitInfo.cs | 4 +- .../Discord.Net.WebSocket.csproj | 8 +-- .../DiscordSocketClient.cs | 2 +- .../DiscordVoiceApiClient.cs | 4 +- .../Channels/ISocketMessageChannel.cs | 3 +- .../Entities/Channels/SocketDMChannel.cs | 6 +-- .../Entities/Channels/SocketGroupChannel.cs | 8 +-- .../Entities/Channels/SocketTextChannel.cs | 8 +-- .../Net/DefaultUdpSocket.cs | 6 --- .../Net/DefaultUdpSocketProvider.cs | 10 +--- .../Net/DefaultWebSocketClient.cs | 13 ++--- .../Net/DefaultWebSocketClientProvider.cs | 10 +--- .../Discord.Net.Webhook.csproj | 4 +- .../DiscordWebhookClient.cs | 3 +- .../WebhookClientHelper.cs | 4 +- .../Discord.Net.Tests.csproj | 10 ++-- .../Tests.ChannelPermissions.cs | 2 +- test/Discord.Net.Tests/Tests.Channels.cs | 52 +++++++++---------- test/Discord.Net.Tests/Tests.Colors.cs | 3 +- test/Discord.Net.Tests/Tests.Emotes.cs | 3 +- test/Discord.Net.Tests/Tests.Permissions.cs | 8 +-- 42 files changed, 135 insertions(+), 229 deletions(-) diff --git a/Discord.Net.targets b/Discord.Net.targets index 958b2053f..079ec7749 100644 --- a/Discord.Net.targets +++ b/Discord.Net.targets @@ -16,13 +16,7 @@ $(VersionSuffix)-$(BuildNumber) build-$(BuildNumber) - - - $(DefineConstants);FILESYSTEM;DEFAULTUDPCLIENT;DEFAULTWEBSOCKET - - - $(DefineConstants);FORMATSTR;UNIXTIME;MSTRYBUFFER;UDPDISPOSE - + $(NoWarn);CS1573;CS1591 true diff --git a/samples/02_commands_framework/02_commands_framework.csproj b/samples/02_commands_framework/02_commands_framework.csproj index 77fdc65e1..f479ee0b0 100644 --- a/samples/02_commands_framework/02_commands_framework.csproj +++ b/samples/02_commands_framework/02_commands_framework.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj index 8ab398ff5..5da3d506d 100644 --- a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj +++ b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj @@ -7,7 +7,7 @@ netstandard1.3 - + diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.csproj b/src/Discord.Net.Commands/Discord.Net.Commands.csproj index eaac79a55..a754486dd 100644 --- a/src/Discord.Net.Commands/Discord.Net.Commands.csproj +++ b/src/Discord.Net.Commands/Discord.Net.Commands.csproj @@ -1,15 +1,19 @@ - + Discord.Net.Commands Discord.Commands A Discord.Net extension adding support for bot commands. - netstandard1.1 + net46;netstandard1.3;netstandard2.0 + netstandard1.3;netstandard2.0 - + + + + \ No newline at end of file diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj index 321803114..6a58367e6 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.csproj +++ b/src/Discord.Net.Core/Discord.Net.Core.csproj @@ -1,15 +1,15 @@ - + Discord.Net.Core Discord The core components for the Discord.Net library. - net45;netstandard1.1;netstandard1.3;netstandard2.0 - netstandard1.1;netstandard1.3;netstandard2.0 + net46;netstandard1.3;netstandard2.0 + netstandard1.3;netstandard2.0 - - + + diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs index 262b865ea..ef5a6fa7a 100644 --- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs @@ -9,10 +9,9 @@ namespace Discord { /// Sends a message to this message channel. Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#if FILESYSTEM /// Sends a file to this text channel, with an optional caption. Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#endif + /// Sends a file to this text channel, with an optional caption. Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.Core/Entities/Image.cs b/src/Discord.Net.Core/Entities/Image.cs index c2c997365..3b946ce80 100644 --- a/src/Discord.Net.Core/Entities/Image.cs +++ b/src/Discord.Net.Core/Entities/Image.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace Discord { /// @@ -15,7 +15,7 @@ namespace Discord { Stream = stream; } -#if FILESYSTEM + /// /// Create the image from a file path. /// @@ -27,6 +27,6 @@ namespace Discord { Stream = File.OpenRead(path); } -#endif + } } diff --git a/src/Discord.Net.Core/Extensions/UserExtensions.cs b/src/Discord.Net.Core/Extensions/UserExtensions.cs index 3296d00fd..951e8ca4b 100644 --- a/src/Discord.Net.Core/Extensions/UserExtensions.cs +++ b/src/Discord.Net.Core/Extensions/UserExtensions.cs @@ -32,7 +32,6 @@ namespace Discord return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); } -#if FILESYSTEM /// /// Sends a file to the user via DM. /// @@ -45,7 +44,6 @@ namespace Discord { return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); } -#endif public static Task BanAsync(this IGuildUser user, int pruneDays = 0, string reason = null, RequestOptions options = null) => user.Guild.AddBanAsync(user, pruneDays, reason, options); diff --git a/src/Discord.Net.Core/Logging/LogManager.cs b/src/Discord.Net.Core/Logging/LogManager.cs index 995a5d96a..a69519fa2 100644 --- a/src/Discord.Net.Core/Logging/LogManager.cs +++ b/src/Discord.Net.Core/Logging/LogManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; namespace Discord.Logging @@ -35,7 +35,7 @@ namespace Discord.Logging } catch { } } -#if FORMATSTR + public async Task LogAsync(LogSeverity severity, string source, FormattableString message, Exception ex = null) { try @@ -45,52 +45,49 @@ namespace Discord.Logging } catch { } } -#endif + public Task ErrorAsync(string source, Exception ex) => LogAsync(LogSeverity.Error, source, ex); public Task ErrorAsync(string source, string message, Exception ex = null) => LogAsync(LogSeverity.Error, source, message, ex); -#if FORMATSTR + public Task ErrorAsync(string source, FormattableString message, Exception ex = null) => LogAsync(LogSeverity.Error, source, message, ex); -#endif + public Task WarningAsync(string source, Exception ex) => LogAsync(LogSeverity.Warning, source, ex); public Task WarningAsync(string source, string message, Exception ex = null) => LogAsync(LogSeverity.Warning, source, message, ex); -#if FORMATSTR + public Task WarningAsync(string source, FormattableString message, Exception ex = null) => LogAsync(LogSeverity.Warning, source, message, ex); -#endif + public Task InfoAsync(string source, Exception ex) => LogAsync(LogSeverity.Info, source, ex); public Task InfoAsync(string source, string message, Exception ex = null) => LogAsync(LogSeverity.Info, source, message, ex); -#if FORMATSTR public Task InfoAsync(string source, FormattableString message, Exception ex = null) => LogAsync(LogSeverity.Info, source, message, ex); -#endif + public Task VerboseAsync(string source, Exception ex) => LogAsync(LogSeverity.Verbose, source, ex); public Task VerboseAsync(string source, string message, Exception ex = null) => LogAsync(LogSeverity.Verbose, source, message, ex); -#if FORMATSTR public Task VerboseAsync(string source, FormattableString message, Exception ex = null) => LogAsync(LogSeverity.Verbose, source, message, ex); -#endif + public Task DebugAsync(string source, Exception ex) => LogAsync(LogSeverity.Debug, source, ex); public Task DebugAsync(string source, string message, Exception ex = null) => LogAsync(LogSeverity.Debug, source, message, ex); -#if FORMATSTR public Task DebugAsync(string source, FormattableString message, Exception ex = null) => LogAsync(LogSeverity.Debug, source, message, ex); -#endif + public Logger CreateLogger(string name) => new Logger(this, name); diff --git a/src/Discord.Net.Core/Logging/Logger.cs b/src/Discord.Net.Core/Logging/Logger.cs index a8d88b2b4..e71c56992 100644 --- a/src/Discord.Net.Core/Logging/Logger.cs +++ b/src/Discord.Net.Core/Logging/Logger.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; namespace Discord.Logging @@ -20,54 +20,53 @@ namespace Discord.Logging => _manager.LogAsync(severity, Name, exception); public Task LogAsync(LogSeverity severity, string message, Exception exception = null) => _manager.LogAsync(severity, Name, message, exception); -#if FORMATSTR public Task LogAsync(LogSeverity severity, FormattableString message, Exception exception = null) => _manager.LogAsync(severity, Name, message, exception); -#endif + public Task ErrorAsync(Exception exception) => _manager.ErrorAsync(Name, exception); public Task ErrorAsync(string message, Exception exception = null) => _manager.ErrorAsync(Name, message, exception); -#if FORMATSTR + public Task ErrorAsync(FormattableString message, Exception exception = null) => _manager.ErrorAsync(Name, message, exception); -#endif + public Task WarningAsync(Exception exception) => _manager.WarningAsync(Name, exception); public Task WarningAsync(string message, Exception exception = null) => _manager.WarningAsync(Name, message, exception); -#if FORMATSTR + public Task WarningAsync(FormattableString message, Exception exception = null) => _manager.WarningAsync(Name, message, exception); -#endif + public Task InfoAsync(Exception exception) => _manager.InfoAsync(Name, exception); public Task InfoAsync(string message, Exception exception = null) => _manager.InfoAsync(Name, message, exception); -#if FORMATSTR + public Task InfoAsync(FormattableString message, Exception exception = null) => _manager.InfoAsync(Name, message, exception); -#endif + public Task VerboseAsync(Exception exception) => _manager.VerboseAsync(Name, exception); public Task VerboseAsync(string message, Exception exception = null) => _manager.VerboseAsync(Name, message, exception); -#if FORMATSTR + public Task VerboseAsync(FormattableString message, Exception exception = null) => _manager.VerboseAsync(Name, message, exception); -#endif + public Task DebugAsync(Exception exception) => _manager.DebugAsync(Name, exception); public Task DebugAsync(string message, Exception exception = null) => _manager.DebugAsync(Name, message, exception); -#if FORMATSTR + public Task DebugAsync(FormattableString message, Exception exception = null) => _manager.DebugAsync(Name, message, exception); -#endif + } } diff --git a/src/Discord.Net.Core/Utils/DateTimeUtils.cs b/src/Discord.Net.Core/Utils/DateTimeUtils.cs index af2126853..e2a8faa75 100644 --- a/src/Discord.Net.Core/Utils/DateTimeUtils.cs +++ b/src/Discord.Net.Core/Utils/DateTimeUtils.cs @@ -1,57 +1,14 @@ -using System; +using System; namespace Discord { //Source: https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/DateTimeOffset.cs internal static class DateTimeUtils { -#if !UNIXTIME - private const long UnixEpochTicks = 621_355_968_000_000_000; - private const long UnixEpochSeconds = 62_135_596_800; - private const long UnixEpochMilliseconds = 62_135_596_800_000; -#endif - public static DateTimeOffset FromTicks(long ticks) => new DateTimeOffset(ticks, TimeSpan.Zero); public static DateTimeOffset? FromTicks(long? ticks) => ticks != null ? new DateTimeOffset(ticks.Value, TimeSpan.Zero) : (DateTimeOffset?)null; - - public static DateTimeOffset FromUnixSeconds(long seconds) - { -#if UNIXTIME - return DateTimeOffset.FromUnixTimeSeconds(seconds); -#else - long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks; - return new DateTimeOffset(ticks, TimeSpan.Zero); -#endif - } - public static DateTimeOffset FromUnixMilliseconds(long milliseconds) - { -#if UNIXTIME - return DateTimeOffset.FromUnixTimeMilliseconds(milliseconds); -#else - long ticks = milliseconds * TimeSpan.TicksPerMillisecond + UnixEpochTicks; - return new DateTimeOffset(ticks, TimeSpan.Zero); -#endif - } - - public static long ToUnixSeconds(DateTimeOffset dto) - { -#if UNIXTIME - return dto.ToUnixTimeSeconds(); -#else - long seconds = dto.UtcDateTime.Ticks / TimeSpan.TicksPerSecond; - return seconds - UnixEpochSeconds; -#endif - } - public static long ToUnixMilliseconds(DateTimeOffset dto) - { -#if UNIXTIME - return dto.ToUnixTimeMilliseconds(); -#else - long milliseconds = dto.UtcDateTime.Ticks / TimeSpan.TicksPerMillisecond; - return milliseconds - UnixEpochMilliseconds; -#endif - } + } } diff --git a/src/Discord.Net.Core/Utils/SnowflakeUtils.cs b/src/Discord.Net.Core/Utils/SnowflakeUtils.cs index c9d0d130b..eecebfb24 100644 --- a/src/Discord.Net.Core/Utils/SnowflakeUtils.cs +++ b/src/Discord.Net.Core/Utils/SnowflakeUtils.cs @@ -5,8 +5,8 @@ namespace Discord public static class SnowflakeUtils { public static DateTimeOffset FromSnowflake(ulong value) - => DateTimeUtils.FromUnixMilliseconds((long)((value >> 22) + 1420070400000UL)); + => DateTimeOffset.FromUnixTimeMilliseconds((long)((value >> 22) + 1420070400000UL)); public static ulong ToSnowflake(DateTimeOffset value) - => ((ulong)DateTimeUtils.ToUnixMilliseconds(value) - 1420070400000UL) << 22; + => ((ulong)value.ToUnixTimeMilliseconds() - 1420070400000UL) << 22; } } diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.csproj b/src/Discord.Net.Rest/Discord.Net.Rest.csproj index 0eb07a4b2..75b69bd04 100644 --- a/src/Discord.Net.Rest/Discord.Net.Rest.csproj +++ b/src/Discord.Net.Rest/Discord.Net.Rest.csproj @@ -1,20 +1,19 @@ - + Discord.Net.Rest Discord.Rest A core Discord.Net library containing the REST client and models. - net45;netstandard1.1;netstandard1.3 - netstandard1.1;netstandard1.3 + net46;netstandard1.3;netstandard2.0 + netstandard1.3;netstandard2.0 - - - + + - + diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs index dbbabbd72..6084ca4dc 100644 --- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs +++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs @@ -168,7 +168,6 @@ namespace Discord.Rest return RestUserMessage.Create(client, channel, client.CurrentUser, model); } -#if FILESYSTEM public static async Task SendFileAsync(IMessageChannel channel, BaseDiscordClient client, string filePath, string text, bool isTTS, Embed embed, RequestOptions options) { @@ -176,7 +175,7 @@ namespace Discord.Rest using (var file = File.OpenRead(filePath)) return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, options).ConfigureAwait(false); } -#endif + public static async Task SendFileAsync(IMessageChannel channel, BaseDiscordClient client, Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) { diff --git a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs index b6f891f40..e0095c7b1 100644 --- a/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs @@ -8,10 +8,9 @@ namespace Discord.Rest { /// Sends a message to this message channel. new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#if FILESYSTEM /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#endif + /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs index 21cd579e6..64efcf24b 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs @@ -65,10 +65,10 @@ namespace Discord.Rest public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -126,10 +126,9 @@ namespace Discord.Rest async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs index 901016a6b..367abfb4a 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs @@ -83,10 +83,10 @@ namespace Discord.Rest public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -136,10 +136,9 @@ namespace Discord.Rest async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 841aad666..b01a88210 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -60,10 +60,10 @@ namespace Discord.Rest public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -131,10 +131,9 @@ namespace Discord.Rest async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs index 8f69388d4..e8b939e65 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RpcVirtualMessageChannel.cs @@ -35,11 +35,10 @@ namespace Discord.Rest public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) + => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) @@ -86,10 +85,9 @@ namespace Discord.Rest async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options); -#if FILESYSTEM async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs index 9213c5d75..8a3c1037b 100644 --- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs +++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs @@ -1,4 +1,4 @@ -using Discord.API; +using Discord.API; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; @@ -25,7 +25,6 @@ namespace Discord.Net.Converters if (converter != null) { property.Converter = converter; - property.MemberConverter = converter; } } else diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs index 3346681b5..c4f5996c5 100644 --- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs +++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs @@ -230,7 +230,7 @@ namespace Discord.Net.Queue #endif } - var now = DateTimeUtils.ToUnixSeconds(DateTimeOffset.UtcNow); + var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); DateTimeOffset? resetTick = null; //Using X-RateLimit-Remaining causes a race condition diff --git a/src/Discord.Net.Rest/Net/RateLimitInfo.cs b/src/Discord.Net.Rest/Net/RateLimitInfo.cs index 9421221ed..a517f290c 100644 --- a/src/Discord.Net.Rest/Net/RateLimitInfo.cs +++ b/src/Discord.Net.Rest/Net/RateLimitInfo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Discord.Net @@ -21,7 +21,7 @@ namespace Discord.Net Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && int.TryParse(temp, out var remaining) ? remaining : (int?)null; Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) && - int.TryParse(temp, out var reset) ? DateTimeUtils.FromUnixSeconds(reset) : (DateTimeOffset?)null; + int.TryParse(temp, out var reset) ? DateTimeOffset.FromUnixTimeSeconds(reset) : (DateTimeOffset?)null; RetryAfter = headers.TryGetValue("Retry-After", out temp) && int.TryParse(temp, out var retryAfter) ? retryAfter : (int?)null; Lag = headers.TryGetValue("Date", out temp) && diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj index 251cdb18b..ddd3b7954 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj @@ -1,11 +1,11 @@ - + Discord.Net.WebSocket Discord.WebSocket A core Discord.Net library containing the WebSocket client and models. - net45;netstandard1.1;netstandard1.3 - netstandard1.1;netstandard1.3 + net46;netstandard1.3;netstandard2.0 + netstandard1.3;netstandard2.0 true @@ -13,6 +13,6 @@ - + diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 72b0b022b..01322a3cc 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -365,7 +365,7 @@ namespace Discord.WebSocket await ApiClient.SendStatusUpdateAsync( status, status == UserStatus.AFK, - statusSince != null ? DateTimeUtils.ToUnixMilliseconds(_statusSince.Value) : (long?)null, + statusSince != null ? _statusSince.Value.ToUnixTimeMilliseconds() : (long?)null, gameModel).ConfigureAwait(false); } diff --git a/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs b/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs index 25dc2cf7b..0eb92caed 100644 --- a/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs +++ b/src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using Discord.API; using Discord.API.Voice; using Discord.Net.Converters; @@ -129,7 +129,7 @@ namespace Discord.Audio //WebSocket public async Task SendHeartbeatAsync(RequestOptions options = null) { - await SendAsync(VoiceOpCode.Heartbeat, DateTimeUtils.ToUnixMilliseconds(DateTimeOffset.UtcNow), options: options).ConfigureAwait(false); + await SendAsync(VoiceOpCode.Heartbeat, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), options: options).ConfigureAwait(false); } public async Task SendIdentityAsync(ulong userId, string sessionId, string token) { diff --git a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs index 971dbe8f1..5fef7e4cd 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs @@ -12,10 +12,9 @@ namespace Discord.WebSocket /// Sends a message to this message channel. new Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#if FILESYSTEM /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); -#endif + /// Sends a file to this text channel, with an optional caption. new Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs index d95d45890..11b7ce25a 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs @@ -69,10 +69,10 @@ namespace Discord.WebSocket public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -135,10 +135,8 @@ namespace Discord.WebSocket => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, mode, options); async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs index 3d6f60db2..81b5cfbf3 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs @@ -97,10 +97,10 @@ namespace Discord.WebSocket public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -199,10 +199,10 @@ namespace Discord.WebSocket => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, mode, options); async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM + async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index 9373c431a..dc68044fe 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -77,10 +77,10 @@ namespace Discord.WebSocket public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); -#if FILESYSTEM + public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); -#endif + public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); @@ -159,10 +159,10 @@ namespace Discord.WebSocket => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, mode, options); async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) => await GetPinnedMessagesAsync(options).ConfigureAwait(false); -#if FILESYSTEM + async Task IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false); -#endif + async Task IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options) => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false); async Task IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Net/DefaultUdpSocket.cs b/src/Discord.Net.WebSocket/Net/DefaultUdpSocket.cs index 6a6194397..251a761d4 100644 --- a/src/Discord.Net.WebSocket/Net/DefaultUdpSocket.cs +++ b/src/Discord.Net.WebSocket/Net/DefaultUdpSocket.cs @@ -1,4 +1,3 @@ -#if DEFAULTUDPCLIENT using System; using System.Net; using System.Net.Sockets; @@ -85,11 +84,7 @@ namespace Discord.Net.Udp if (_udp != null) { -#if UDPDISPOSE try { _udp.Dispose(); } -#else - try { _udp.Close(); } -#endif catch { } _udp = null; } @@ -132,4 +127,3 @@ namespace Discord.Net.Udp } } } -#endif \ No newline at end of file diff --git a/src/Discord.Net.WebSocket/Net/DefaultUdpSocketProvider.cs b/src/Discord.Net.WebSocket/Net/DefaultUdpSocketProvider.cs index 82b6ec4c0..d701fa79a 100644 --- a/src/Discord.Net.WebSocket/Net/DefaultUdpSocketProvider.cs +++ b/src/Discord.Net.WebSocket/Net/DefaultUdpSocketProvider.cs @@ -4,7 +4,6 @@ namespace Discord.Net.Udp { public static class DefaultUdpSocketProvider { -#if DEFAULTUDPCLIENT public static readonly UdpSocketProvider Instance = () => { try @@ -16,12 +15,5 @@ namespace Discord.Net.Udp throw new PlatformNotSupportedException("The default UdpSocketProvider is not supported on this platform.", ex); } }; -#else - public static readonly UdpSocketProvider Instance = () => - { - throw new PlatformNotSupportedException("The default UdpSocketProvider is not supported on this platform.\n" + - "You must specify a UdpSocketProvider or target a runtime supporting .NET Standard 1.3, such as .NET Framework 4.6+."); - }; -#endif } -} \ No newline at end of file +} diff --git a/src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs b/src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs index a250acec9..c60368da0 100644 --- a/src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs +++ b/src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs @@ -1,4 +1,3 @@ -#if DEFAULTWEBSOCKET using System; using System.Collections.Generic; using System.ComponentModel; @@ -209,14 +208,9 @@ namespace Discord.Net.WebSockets //Use the internal buffer if we can get it resultCount = (int)stream.Length; -#if MSTRYBUFFER - if (stream.TryGetBuffer(out var streamBuffer)) - result = streamBuffer.Array; - else - result = stream.ToArray(); -#else - result = stream.GetBuffer(); -#endif + + result = stream.TryGetBuffer(out var streamBuffer) ? streamBuffer.Array : stream.ToArray(); + } } else @@ -248,4 +242,3 @@ namespace Discord.Net.WebSockets } } } -#endif \ No newline at end of file diff --git a/src/Discord.Net.WebSocket/Net/DefaultWebSocketClientProvider.cs b/src/Discord.Net.WebSocket/Net/DefaultWebSocketClientProvider.cs index 68bd67c5b..2d66d5900 100644 --- a/src/Discord.Net.WebSocket/Net/DefaultWebSocketClientProvider.cs +++ b/src/Discord.Net.WebSocket/Net/DefaultWebSocketClientProvider.cs @@ -5,7 +5,6 @@ namespace Discord.Net.WebSockets { public static class DefaultWebSocketProvider { -#if DEFAULTWEBSOCKET public static readonly WebSocketProvider Instance = Create(); public static WebSocketProvider Create(IWebProxy proxy = null) @@ -22,12 +21,5 @@ namespace Discord.Net.WebSockets } }; } -#else - public static readonly WebSocketProvider Instance = () => - { - throw new PlatformNotSupportedException("The default WebSocketProvider is not supported on this platform.\n" + - "You must specify a WebSocketProvider or target a runtime supporting .NET Standard 1.3, such as .NET Framework 4.6+."); - }; -#endif } -} \ No newline at end of file +} diff --git a/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj b/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj index 7c224e01e..ba7bbcff8 100644 --- a/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj +++ b/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj @@ -1,10 +1,10 @@ - + Discord.Net.Webhook Discord.Webhook A core Discord.Net library containing the Webhook client and models. - netstandard1.1 + netstandard1.3 diff --git a/src/Discord.Net.Webhook/DiscordWebhookClient.cs b/src/Discord.Net.Webhook/DiscordWebhookClient.cs index 2dea1c1d1..67a5462be 100644 --- a/src/Discord.Net.Webhook/DiscordWebhookClient.cs +++ b/src/Discord.Net.Webhook/DiscordWebhookClient.cs @@ -67,12 +67,11 @@ namespace Discord.Webhook string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendMessageAsync(this, text, isTTS, embeds, username, avatarUrl, options); -#if FILESYSTEM /// Send a message to the channel for this webhook with an attachment. Returns the ID of the created message. public Task SendFileAsync(string filePath, string text, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendFileAsync(this, filePath, text, isTTS, embeds, username, avatarUrl, options); -#endif + /// Send a message to the channel for this webhook with an attachment. Returns the ID of the created message. public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) diff --git a/src/Discord.Net.Webhook/WebhookClientHelper.cs b/src/Discord.Net.Webhook/WebhookClientHelper.cs index 1116662a6..d3cac9703 100644 --- a/src/Discord.Net.Webhook/WebhookClientHelper.cs +++ b/src/Discord.Net.Webhook/WebhookClientHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -33,7 +33,6 @@ namespace Discord.Webhook var model = await client.ApiClient.CreateWebhookMessageAsync(client.Webhook.Id, args, options: options).ConfigureAwait(false); return model.Id; } -#if FILESYSTEM public static async Task SendFileAsync(DiscordWebhookClient client, string filePath, string text, bool isTTS, IEnumerable embeds, string username, string avatarUrl, RequestOptions options) { @@ -41,7 +40,6 @@ namespace Discord.Webhook using (var file = File.OpenRead(filePath)) return await SendFileAsync(client, file, filename, text, isTTS, embeds, username, avatarUrl, options).ConfigureAwait(false); } -#endif public static async Task SendFileAsync(DiscordWebhookClient client, Stream stream, string filename, string text, bool isTTS, IEnumerable embeds, string username, string avatarUrl, RequestOptions options) { diff --git a/test/Discord.Net.Tests/Discord.Net.Tests.csproj b/test/Discord.Net.Tests/Discord.Net.Tests.csproj index 204dca5c4..60491a96f 100644 --- a/test/Discord.Net.Tests/Discord.Net.Tests.csproj +++ b/test/Discord.Net.Tests/Discord.Net.Tests.csproj @@ -21,10 +21,10 @@ - - - - - + + + + + diff --git a/test/Discord.Net.Tests/Tests.ChannelPermissions.cs b/test/Discord.Net.Tests/Tests.ChannelPermissions.cs index b37a1195e..da969b320 100644 --- a/test/Discord.Net.Tests/Tests.ChannelPermissions.cs +++ b/test/Discord.Net.Tests/Tests.ChannelPermissions.cs @@ -84,7 +84,7 @@ namespace Discord Assert.Equal(groupChannel, ChannelPermissions.Group.RawValue); return Task.CompletedTask; } - + [Fact] public Task TestChannelPermissionModify() { // test channel permission modify diff --git a/test/Discord.Net.Tests/Tests.Channels.cs b/test/Discord.Net.Tests/Tests.Channels.cs index b528ca5fb..cd629faa4 100644 --- a/test/Discord.Net.Tests/Tests.Channels.cs +++ b/test/Discord.Net.Tests/Tests.Channels.cs @@ -49,35 +49,35 @@ namespace Discord } private static void CheckTextChannels(RestGuild guild, params RestTextChannel[] textChannels) { - Assert.Equal(textChannels.Length, 5); + Assert.Equal(5, textChannels.Length); Assert.All(textChannels, x => { Assert.NotNull(x); - Assert.NotEqual(x.Id, 0UL); + Assert.NotEqual(0UL, x.Id); Assert.True(x.Position >= 0); }); - var text1 = textChannels.Where(x => x.Name == "text1").FirstOrDefault(); - var text2 = textChannels.Where(x => x.Name == "text2").FirstOrDefault(); - var text3 = textChannels.Where(x => x.Name == "text3").FirstOrDefault(); - var text4 = textChannels.Where(x => x.Name == "text4").FirstOrDefault(); - var text5 = textChannels.Where(x => x.Name == "text5").FirstOrDefault(); + var text1 = textChannels.FirstOrDefault(x => x.Name == "text1"); + var text2 = textChannels.FirstOrDefault(x => x.Name == "text2"); + var text3 = textChannels.FirstOrDefault(x => x.Name == "text3"); + var text4 = textChannels.FirstOrDefault(x => x.Name == "text4"); + var text5 = textChannels.FirstOrDefault(x => x.Name == "text5"); Assert.NotNull(text1); //Assert.True(text1.Id == guild.DefaultChannelId); - Assert.Equal(text1.Position, 1); - Assert.Equal(text1.Topic, "Topic1"); + Assert.Equal(1, text1.Position); + Assert.Equal("Topic1", text1.Topic); Assert.NotNull(text2); - Assert.Equal(text2.Position, 2); + Assert.Equal(2, text2.Position); Assert.Null(text2.Topic); Assert.NotNull(text3); - Assert.Equal(text3.Topic, "Topic2"); + Assert.Equal("Topic2", text3.Topic); Assert.NotNull(text4); - Assert.Equal(text4.Position, 3); - Assert.Equal(text4.Topic, "Topic2"); + Assert.Equal(3, text4.Position); + Assert.Equal("Topic2", text4.Topic); Assert.NotNull(text5); Assert.Null(text5.Topic); @@ -114,31 +114,31 @@ namespace Discord } private static void CheckVoiceChannels(params RestVoiceChannel[] voiceChannels) { - Assert.Equal(voiceChannels.Length, 3); + Assert.Equal(3, voiceChannels.Length); Assert.All(voiceChannels, x => { Assert.NotNull(x); - Assert.NotEqual(x.Id, 0UL); - Assert.NotEqual(x.UserLimit, 0); + Assert.NotEqual(0UL, x.Id); + Assert.NotEqual(0, x.UserLimit); Assert.True(x.Bitrate > 0); Assert.True(x.Position >= 0); }); - var voice1 = voiceChannels.Where(x => x.Name == "voice1").FirstOrDefault(); - var voice2 = voiceChannels.Where(x => x.Name == "voice2").FirstOrDefault(); - var voice3 = voiceChannels.Where(x => x.Name == "voice3").FirstOrDefault(); + var voice1 = voiceChannels.FirstOrDefault(x => x.Name == "voice1"); + var voice2 = voiceChannels.FirstOrDefault(x => x.Name == "voice2"); + var voice3 = voiceChannels.FirstOrDefault(x => x.Name == "voice3"); Assert.NotNull(voice1); - Assert.Equal(voice1.Bitrate, 96000); - Assert.Equal(voice1.Position, 1); + Assert.Equal(96000, voice1.Bitrate); + Assert.Equal(1, voice1.Position); Assert.NotNull(voice2); - Assert.Equal(voice2.UserLimit, null); + Assert.Null(voice2.UserLimit); Assert.NotNull(voice3); - Assert.Equal(voice3.Bitrate, 8000); - Assert.Equal(voice3.Position, 1); - Assert.Equal(voice3.UserLimit, 16); + Assert.Equal(8000, voice3.Bitrate); + Assert.Equal(1, voice3.Position); + Assert.Equal(16, voice3.UserLimit); } } -} \ No newline at end of file +} diff --git a/test/Discord.Net.Tests/Tests.Colors.cs b/test/Discord.Net.Tests/Tests.Colors.cs index 591778972..10b0bbdac 100644 --- a/test/Discord.Net.Tests/Tests.Colors.cs +++ b/test/Discord.Net.Tests/Tests.Colors.cs @@ -1,4 +1,4 @@ -using System; +using System; using Xunit; namespace Discord @@ -12,6 +12,7 @@ namespace Discord Assert.Equal(uint.MinValue, new Color(uint.MinValue).RawValue); Assert.Equal(uint.MaxValue, new Color(uint.MaxValue).RawValue); } + [Fact] public void Color_Default() { Assert.Equal(0u, Color.Default.RawValue); diff --git a/test/Discord.Net.Tests/Tests.Emotes.cs b/test/Discord.Net.Tests/Tests.Emotes.cs index 334975ce4..eeadbddf8 100644 --- a/test/Discord.Net.Tests/Tests.Emotes.cs +++ b/test/Discord.Net.Tests/Tests.Emotes.cs @@ -1,4 +1,4 @@ -using System; +using System; using Xunit; namespace Discord @@ -34,6 +34,7 @@ namespace Discord Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1514056829775), emote.CreatedAt); Assert.EndsWith("gif", emote.Url); } + [Fact] public void Test_Invalid_Amimated_Emote_Parse() { Assert.False(Emote.TryParse("", out _)); diff --git a/test/Discord.Net.Tests/Tests.Permissions.cs b/test/Discord.Net.Tests/Tests.Permissions.cs index e22659d15..6e71da1b1 100644 --- a/test/Discord.Net.Tests/Tests.Permissions.cs +++ b/test/Discord.Net.Tests/Tests.Permissions.cs @@ -25,15 +25,15 @@ namespace Discord // check that toggling the bit works Permissions.UnsetFlag(ref rawValue, flagValue); - Assert.Equal(false, Permissions.GetValue(rawValue, flagValue)); + Assert.False(Permissions.GetValue(rawValue, flagValue)); Permissions.SetFlag(ref rawValue, flagValue); - Assert.Equal(true, Permissions.GetValue(rawValue, flagValue)); + Assert.True(Permissions.GetValue(rawValue, flagValue)); // do the same, but with the SetValue method Permissions.SetValue(ref rawValue, true, flagValue); - Assert.Equal(true, Permissions.GetValue(rawValue, flagValue)); + Assert.True(Permissions.GetValue(rawValue, flagValue)); Permissions.SetValue(ref rawValue, false, flagValue); - Assert.Equal(false, Permissions.GetValue(rawValue, flagValue)); + Assert.False(Permissions.GetValue(rawValue, flagValue)); } /// From fa759a22eac25183eb0fecf6cd0fbbf7f476fa11 Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Fri, 25 May 2018 06:38:59 -0700 Subject: [PATCH 11/11] Remove Build Warnings for Obsolete Guild Permission Read Messages (#1067) - Replaces the usages of `ReadMessages` with `ViewChannel` - Renames the read message parameters of `GuildPermissions#Modify` to be view channel as well --- .../Entities/Permissions/GuildPermissions.cs | 12 ++++++------ test/Discord.Net.Tests/Tests.GuildPermissions.cs | 10 +++++----- test/Discord.Net.Tests/Tests.Permissions.cs | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs index dcebeb20d..aa914eda1 100644 --- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs +++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs @@ -87,7 +87,7 @@ namespace Discord private GuildPermissions(ulong initialValue, bool? createInstantInvite = null, bool? kickMembers = null, bool? banMembers = null, bool? administrator = null, bool? manageChannels = null, bool? manageGuild = null, bool? addReactions = null, bool? viewAuditLog = null, - bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null, + bool? viewChannel = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null, bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null, bool? useExternalEmojis = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null, bool? moveMembers = null, bool? useVoiceActivation = null, bool? changeNickname = null, bool? manageNicknames = null, @@ -103,7 +103,7 @@ namespace Discord Permissions.SetValue(ref value, manageGuild, GuildPermission.ManageGuild); Permissions.SetValue(ref value, addReactions, GuildPermission.AddReactions); Permissions.SetValue(ref value, viewAuditLog, GuildPermission.ViewAuditLog); - Permissions.SetValue(ref value, readMessages, GuildPermission.ReadMessages); + Permissions.SetValue(ref value, viewChannel, GuildPermission.ViewChannel); Permissions.SetValue(ref value, sendMessages, GuildPermission.SendMessages); Permissions.SetValue(ref value, sendTTSMessages, GuildPermission.SendTTSMessages); Permissions.SetValue(ref value, manageMessages, GuildPermission.ManageMessages); @@ -131,14 +131,14 @@ namespace Discord public GuildPermissions(bool createInstantInvite = false, bool kickMembers = false, bool banMembers = false, bool administrator = false, bool manageChannels = false, bool manageGuild = false, bool addReactions = false, bool viewAuditLog = false, - bool readMessages = false, bool sendMessages = false, bool sendTTSMessages = false, bool manageMessages = false, + bool viewChannel = false, bool sendMessages = false, bool sendTTSMessages = false, bool manageMessages = false, bool embedLinks = false, bool attachFiles = false, bool readMessageHistory = false, bool mentionEveryone = false, bool useExternalEmojis = false, bool connect = false, bool speak = false, bool muteMembers = false, bool deafenMembers = false, bool moveMembers = false, bool useVoiceActivation = false, bool? changeNickname = false, bool? manageNicknames = false, bool manageRoles = false, bool manageWebhooks = false, bool manageEmojis = false) : this(0, createInstantInvite: createInstantInvite, manageRoles: manageRoles, kickMembers: kickMembers, banMembers: banMembers, administrator: administrator, manageChannels: manageChannels, manageGuild: manageGuild, addReactions: addReactions, - viewAuditLog: viewAuditLog, readMessages: readMessages, sendMessages: sendMessages, sendTTSMessages: sendTTSMessages, + viewAuditLog: viewAuditLog, viewChannel: viewChannel, sendMessages: sendMessages, sendTTSMessages: sendTTSMessages, manageMessages: manageMessages, embedLinks: embedLinks, attachFiles: attachFiles, readMessageHistory: readMessageHistory, mentionEveryone: mentionEveryone, useExternalEmojis: useExternalEmojis, connect: connect, speak: speak, muteMembers: muteMembers, deafenMembers: deafenMembers, moveMembers: moveMembers, useVoiceActivation: useVoiceActivation, changeNickname: changeNickname, @@ -149,13 +149,13 @@ namespace Discord public GuildPermissions Modify(bool? createInstantInvite = null, bool? kickMembers = null, bool? banMembers = null, bool? administrator = null, bool? manageChannels = null, bool? manageGuild = null, bool? addReactions = null, bool? viewAuditLog = null, - bool? readMessages = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null, + bool? viewChannel = null, bool? sendMessages = null, bool? sendTTSMessages = null, bool? manageMessages = null, bool? embedLinks = null, bool? attachFiles = null, bool? readMessageHistory = null, bool? mentionEveryone = null, bool? useExternalEmojis = null, bool? connect = null, bool? speak = null, bool? muteMembers = null, bool? deafenMembers = null, bool? moveMembers = null, bool? useVoiceActivation = null, bool? changeNickname = null, bool? manageNicknames = null, bool? manageRoles = null, bool? manageWebhooks = null, bool? manageEmojis = null) => new GuildPermissions(RawValue, createInstantInvite, kickMembers, banMembers, administrator, manageChannels, manageGuild, addReactions, - viewAuditLog, readMessages, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, + viewAuditLog, viewChannel, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, moveMembers, useVoiceActivation, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis); diff --git a/test/Discord.Net.Tests/Tests.GuildPermissions.cs b/test/Discord.Net.Tests/Tests.GuildPermissions.cs index a562f4afb..2b7c39341 100644 --- a/test/Discord.Net.Tests/Tests.GuildPermissions.cs +++ b/test/Discord.Net.Tests/Tests.GuildPermissions.cs @@ -138,12 +138,12 @@ namespace Discord // individual permission test - perm = perm.Modify(readMessages: true); - Assert.True(perm.ReadMessages); - Assert.Equal(perm.RawValue, (ulong)GuildPermission.ReadMessages); + perm = perm.Modify(viewChannel: true); + Assert.True(perm.ViewChannel); + Assert.Equal(perm.RawValue, (ulong)GuildPermission.ViewChannel); - perm = perm.Modify(readMessages: false); - Assert.False(perm.ReadMessages); + perm = perm.Modify(viewChannel: false); + Assert.False(perm.ViewChannel); Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); diff --git a/test/Discord.Net.Tests/Tests.Permissions.cs b/test/Discord.Net.Tests/Tests.Permissions.cs index 6e71da1b1..0516337da 100644 --- a/test/Discord.Net.Tests/Tests.Permissions.cs +++ b/test/Discord.Net.Tests/Tests.Permissions.cs @@ -280,7 +280,7 @@ namespace Discord TestHelper(value, GuildPermission.ManageGuild, false); TestHelper(value, GuildPermission.AddReactions, false); TestHelper(value, GuildPermission.ViewAuditLog, false); - TestHelper(value, GuildPermission.ReadMessages, false); + TestHelper(value, GuildPermission.ViewChannel, false); TestHelper(value, GuildPermission.SendMessages, false); TestHelper(value, GuildPermission.SendTTSMessages, false); TestHelper(value, GuildPermission.ManageMessages, false); @@ -323,7 +323,7 @@ namespace Discord TestHelper(value, GuildPermission.ManageGuild, true); TestHelper(value, GuildPermission.AddReactions, true); TestHelper(value, GuildPermission.ViewAuditLog, true); - TestHelper(value, GuildPermission.ReadMessages, true); + TestHelper(value, GuildPermission.ViewChannel, true); TestHelper(value, GuildPermission.SendMessages, true); TestHelper(value, GuildPermission.SendTTSMessages, true); TestHelper(value, GuildPermission.ManageMessages, true); @@ -367,7 +367,7 @@ namespace Discord TestHelper(value, GuildPermission.ManageGuild, false); TestHelper(value, GuildPermission.AddReactions, false); TestHelper(value, GuildPermission.ViewAuditLog, false); - TestHelper(value, GuildPermission.ReadMessages, false); + TestHelper(value, GuildPermission.ViewChannel, false); TestHelper(value, GuildPermission.SendMessages, true); TestHelper(value, GuildPermission.SendTTSMessages, true); TestHelper(value, GuildPermission.ManageMessages, false);