diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 387ceda6a..5a1d48082 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -16,18 +16,23 @@ jobs: pool: vmImage: 'ubuntu-16.04' steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + packageType: 'sdk' + version: '3.x' - template: azure/build.yml - job: Windows_build pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' condition: ne(variables['Build.SourceBranch'], 'refs/heads/dev') steps: - template: azure/build.yml - job: Windows_deploy pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' condition: | and ( succeeded(), diff --git a/azure/deploy.yml b/azure/deploy.yml index f2affe667..61994299e 100644 --- a/azure/deploy.yml +++ b/azure/deploy.yml @@ -1,32 +1,35 @@ steps: - script: | - dotnet pack "src\Discord.Net.Core\Discord.Net.Core.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.Rest\Discord.Net.Rest.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.Commands\Discord.Net.Commands.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) - dotnet pack "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "../../artifacts/" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Core\Discord.Net.Core.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Rest\Discord.Net.Rest.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Commands\Discord.Net.Commands.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) + dotnet pack "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) -o "$(Build.ArtifactStagingDirectory)" /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) displayName: Pack projects -- task: NuGet@0 - inputs: - command: pack - arguments: src/Discord.Net/Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix="" +- task: NuGetCommand@2 displayName: Pack metapackage (release mode) condition: eq(variables['buildTag'], True) - -- task: NuGet@0 inputs: - command: pack - arguments: src/Discord.Net/Discord.Net.nuspec -OutputDirectory "artifacts" -properties suffix="-$(buildNumber)" + command: 'pack' + packagesToPack: 'src/Discord.Net/Discord.Net.nuspec' + versioningScheme: 'off' + +- task: NuGetCommand@2 displayName: Pack metapackage condition: eq(variables['buildTag'], False) + inputs: + command: 'pack' + packagesToPack: 'src/Discord.Net/Discord.Net.nuspec' + versioningScheme: 'off' + buildProperties: 'suffix=-$(buildNumber)' - task: NuGetCommand@2 displayName: Push to NuGet inputs: command: push nuGetFeedType: external - packagesToPush: 'artifacts/*.nupkg' + packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' publishFeedCredentials: myget-discord diff --git a/azure/docs.bat b/azure/docs.bat index 572534cee..504e12991 100644 --- a/azure/docs.bat +++ b/azure/docs.bat @@ -5,7 +5,8 @@ ECHO remove old 'latest' ECHO Y | RMDIR /S docs-static\latest || EXIT /B 1 ECHO build docs -docfx.console\tools\docfx.exe docs/docfx.json -o docs-static/latest/ || EXIT /B 1 +docfx.console\tools\docfx.exe docs/docfx.json -o docs-staging || EXIT /B 1 +ROBOCOPY docs-staging\_site docs-static\latest /MIR ECHO commit and deploy git config --global user.name "Discord.Net CI Robot" && git config --global user.email "robot@foxbot.me" diff --git a/docs/guides/commands/intro.md b/docs/guides/commands/intro.md index c815175bd..f8ff1b596 100644 --- a/docs/guides/commands/intro.md +++ b/docs/guides/commands/intro.md @@ -111,7 +111,7 @@ optional, give it a default value (i.e., `int num = 0`). #### Parameters with Spaces -To accept a comma-separated list, set the parameter to `params Type[]`. +To accept a space-separated list, set the parameter to `params Type[]`. Should a parameter include spaces, the parameter **must** be wrapped in quotes. For example, for a command with a parameter @@ -218,4 +218,4 @@ Submodules are "modules" that reside within another one. Typically, submodules are used to create nested groups (although not required to create nested groups). -[!code-csharp[Groups and Submodules](samples/intro/groups.cs)] \ No newline at end of file +[!code-csharp[Groups and Submodules](samples/intro/groups.cs)] diff --git a/samples/01_basic_ping_bot/01_basic_ping_bot.csproj b/samples/01_basic_ping_bot/01_basic_ping_bot.csproj index 5484e3d55..4b4e35e3f 100644 --- a/samples/01_basic_ping_bot/01_basic_ping_bot.csproj +++ b/samples/01_basic_ping_bot/01_basic_ping_bot.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.0 + netcoreapp3.0 diff --git a/samples/02_commands_framework/02_commands_framework.csproj b/samples/02_commands_framework/02_commands_framework.csproj index f479ee0b0..84b30aa99 100644 --- a/samples/02_commands_framework/02_commands_framework.csproj +++ b/samples/02_commands_framework/02_commands_framework.csproj @@ -2,11 +2,11 @@ Exe - netcoreapp2.0 + netcoreapp3.0 - + diff --git a/samples/03_sharded_client/03_sharded_client.csproj b/samples/03_sharded_client/03_sharded_client.csproj index 5d76961cd..a6599c117 100644 --- a/samples/03_sharded_client/03_sharded_client.csproj +++ b/samples/03_sharded_client/03_sharded_client.csproj @@ -2,10 +2,14 @@ Exe - netcoreapp2.1 + netcoreapp3.0 _03_sharded_client + + + + diff --git a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj index 5da3d506d..1b2ee45bf 100644 --- a/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj +++ b/src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj @@ -1,13 +1,13 @@ - + Discord.Net.Analyzers Discord.Analyzers A Discord.Net extension adding support for design-time analysis of the API usage. - netstandard1.3 + netstandard2.0;netstandard2.1 - + diff --git a/src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs b/src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs index 0760d019f..38d3f39d4 100644 --- a/src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs +++ b/src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; @@ -24,6 +24,8 @@ namespace Discord.Analyzers public override void Initialize(AnalysisContext context) { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterSyntaxNodeAction(AnalyzeMemberAccess, SyntaxKind.SimpleMemberAccessExpression); } diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.csproj b/src/Discord.Net.Commands/Discord.Net.Commands.csproj index 1bef1bfea..95e7db491 100644 --- a/src/Discord.Net.Commands/Discord.Net.Commands.csproj +++ b/src/Discord.Net.Commands/Discord.Net.Commands.csproj @@ -4,16 +4,11 @@ Discord.Net.Commands Discord.Commands A Discord.Net extension adding support for bot commands. - net46;netstandard1.3;netstandard2.0 - netstandard1.3;netstandard2.0 + net461;netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1 - - - - - - + diff --git a/src/Discord.Net.Commands/Readers/UserTypeReader.cs b/src/Discord.Net.Commands/Readers/UserTypeReader.cs index 6d9f1dd8c..c0104e341 100644 --- a/src/Discord.Net.Commands/Readers/UserTypeReader.cs +++ b/src/Discord.Net.Commands/Readers/UserTypeReader.cs @@ -49,7 +49,7 @@ namespace Discord.Commands string username = input.Substring(0, index); if (ushort.TryParse(input.Substring(index + 1), out ushort discriminator)) { - var channelUser = await channelUsers.FirstOrDefault(x => x.DiscriminatorValue == discriminator && + var channelUser = await channelUsers.FirstOrDefaultAsync(x => x.DiscriminatorValue == discriminator && string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false); AddResult(results, channelUser as T, channelUser?.Username == username ? 0.85f : 0.75f); diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj index 20e57d346..dd2f2afe3 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.csproj +++ b/src/Discord.Net.Core/Discord.Net.Core.csproj @@ -4,13 +4,13 @@ Discord.Net.Core Discord The core components for the Discord.Net library. - net46;netstandard1.3;netstandard2.0 - netstandard1.3;netstandard2.0 + net461;netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1 - + - + all diff --git a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs index e13536a97..ec31019af 100644 --- a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs +++ b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs @@ -1,3 +1,5 @@ +using System.Globalization; + namespace Discord { /// @@ -84,5 +86,23 @@ namespace Discord /// are enabled, without the need to manipulate the logic of the flag. /// public Optional SystemChannelFlags { get; set; } + /// + /// Gets or sets the preferred locale of the guild in IETF BCP 47 language tag format. + /// + /// + /// This property takes precedence over . + /// When it is set, the value of + /// will not be used. + /// + public Optional PreferredLocale { get; set; } + /// + /// Gets or sets the preferred locale of the guild. + /// + /// + /// The property takes precedence + /// over this property. When is set, + /// the value of will be unused. + /// + public Optional PreferredCulture { get; set; } } } diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index d463d86df..213091ad4 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -1,6 +1,7 @@ using Discord.Audio; using System; using System.Collections.Generic; +using System.Globalization; using System.Threading.Tasks; namespace Discord @@ -249,6 +250,24 @@ namespace Discord /// int PremiumSubscriptionCount { get; } + /// + /// Gets the preferred locale of this guild in IETF BCP 47 + /// language tag format. + /// + /// + /// The preferred locale of the guild in IETF BCP 47 + /// language tag format. + /// + string PreferredLocale { get; } + + /// + /// Gets the preferred culture of this guild. + /// + /// + /// The preferred culture information of this guild. + /// + CultureInfo PreferredCulture { get; } + /// /// Modifies this guild. /// diff --git a/src/Discord.Net.Core/Entities/Roles/Color.cs b/src/Discord.Net.Core/Entities/Roles/Color.cs index 6bfead3d6..b522ae47e 100644 --- a/src/Discord.Net.Core/Entities/Roles/Color.cs +++ b/src/Discord.Net.Core/Entities/Roles/Color.cs @@ -1,8 +1,6 @@ using System; using System.Diagnostics; -#if NETSTANDARD2_0 || NET45 using StandardColor = System.Drawing.Color; -#endif namespace Discord { @@ -190,12 +188,10 @@ namespace Discord public override int GetHashCode() => RawValue.GetHashCode(); -#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 /// /// Gets the hexadecimal representation of the color (e.g. #000ccc). diff --git a/src/Discord.Net.Core/Extensions/AsyncEnumerableExtensions.cs b/src/Discord.Net.Core/Extensions/AsyncEnumerableExtensions.cs index 282d20517..d96076259 100644 --- a/src/Discord.Net.Core/Extensions/AsyncEnumerableExtensions.cs +++ b/src/Discord.Net.Core/Extensions/AsyncEnumerableExtensions.cs @@ -15,7 +15,7 @@ namespace Discord /// Flattens the specified pages into one asynchronously. public static async Task> FlattenAsync(this IAsyncEnumerable> source) { - return await source.Flatten().ToArray().ConfigureAwait(false); + return await source.Flatten().ToArrayAsync().ConfigureAwait(false); } /// Flattens the specified pages into one . public static IAsyncEnumerable Flatten(this IAsyncEnumerable> source) diff --git a/src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs b/src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs index a31721875..84209902a 100644 --- a/src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs +++ b/src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs @@ -25,26 +25,28 @@ namespace Discord _nextPage = nextPage; } - public IAsyncEnumerator> GetEnumerator() => new Enumerator(this); + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken()) => new Enumerator(this, cancellationToken); internal class Enumerator : IAsyncEnumerator> { private readonly PagedAsyncEnumerable _source; + private readonly CancellationToken _token; private readonly PageInfo _info; public IReadOnlyCollection Current { get; private set; } - public Enumerator(PagedAsyncEnumerable source) + public Enumerator(PagedAsyncEnumerable source, CancellationToken token) { _source = source; + _token = token; _info = new PageInfo(source._start, source._count, source.PageSize); } - public async Task MoveNext(CancellationToken cancelToken) + public async ValueTask MoveNextAsync() { if (_info.Remaining == 0) return false; - var data = await _source._getPage(_info, cancelToken).ConfigureAwait(false); + var data = await _source._getPage(_info, _token).ConfigureAwait(false); Current = new Page(_info, data); _info.Page++; @@ -71,7 +73,11 @@ namespace Discord return true; } - public void Dispose() { Current = null; } + public ValueTask DisposeAsync() + { + Current = null; + return default; + } } } } diff --git a/src/Discord.Net.Examples/Discord.Net.Examples.csproj b/src/Discord.Net.Examples/Discord.Net.Examples.csproj index b02d2e6d8..ec0253428 100644 --- a/src/Discord.Net.Examples/Discord.Net.Examples.csproj +++ b/src/Discord.Net.Examples/Discord.Net.Examples.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -15,7 +15,7 @@ - + diff --git a/src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj b/src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj index bfd0983ce..e143340e1 100644 --- a/src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj +++ b/src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj @@ -1,10 +1,10 @@ - + Discord.Net.Providers.WS4Net Discord.Providers.WS4Net An optional WebSocket client provider for Discord.Net using WebSocket4Net - netstandard1.3 + netstandard2.0 diff --git a/src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs b/src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs index 166e767d0..b56f3b4f0 100644 --- a/src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs +++ b/src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs @@ -1,4 +1,4 @@ -using Discord.Net.WebSockets; +using Discord.Net.WebSockets; namespace Discord.Net.Providers.WS4Net { diff --git a/src/Discord.Net.Rest/API/Common/Guild.cs b/src/Discord.Net.Rest/API/Common/Guild.cs index 343d5b12c..56bd841ea 100644 --- a/src/Discord.Net.Rest/API/Common/Guild.cs +++ b/src/Discord.Net.Rest/API/Common/Guild.cs @@ -58,5 +58,7 @@ namespace Discord.API public SystemChannelMessageDeny SystemChannelFlags { get; set; } [JsonProperty("premium_subscription_count")] public int? PremiumSubscriptionCount { get; set; } + [JsonProperty("preferred_locale")] + public string PreferredLocale { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs index 9c519d3a8..6341b63b6 100644 --- a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs +++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs @@ -32,5 +32,7 @@ namespace Discord.API.Rest public Optional ExplicitContentFilter { get; set; } [JsonProperty("system_channel_flags")] public Optional SystemChannelFlags { get; set; } + [JsonProperty("preferred_locale")] + public string PreferredLocale { get; set; } } } diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.csproj b/src/Discord.Net.Rest/Discord.Net.Rest.csproj index 75b69bd04..b9592f18d 100644 --- a/src/Discord.Net.Rest/Discord.Net.Rest.csproj +++ b/src/Discord.Net.Rest/Discord.Net.Rest.csproj @@ -4,16 +4,13 @@ Discord.Net.Rest Discord.Rest A core Discord.Net library containing the REST client and models. - net46;netstandard1.3;netstandard2.0 - netstandard1.3;netstandard2.0 + net461;netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1 - - - - + diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index 3f5565ccf..05a520547 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -68,6 +68,12 @@ namespace Discord.Rest if (args.SystemChannelFlags.IsSpecified) apiArgs.SystemChannelFlags = args.SystemChannelFlags.Value; + // PreferredLocale takes precedence over PreferredCulture + if (args.PreferredLocale.IsSpecified) + apiArgs.PreferredLocale = args.PreferredLocale.Value; + else if (args.PreferredCulture.IsSpecified) + apiArgs.PreferredLocale = args.PreferredCulture.Value.Name; + return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); } /// is null. diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index cd142b184..e9e4d3290 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using EmbedModel = Discord.API.GuildEmbed; @@ -64,6 +65,11 @@ namespace Discord.Rest public string Description { get; private set; } /// public int PremiumSubscriptionCount { get; private set; } + /// + public string PreferredLocale { get; private set; } + + /// + public CultureInfo PreferredCulture { get; private set; } /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); @@ -124,6 +130,8 @@ namespace Discord.Rest SystemChannelFlags = model.SystemChannelFlags; Description = model.Description; PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); + PreferredLocale = model.PreferredLocale; + PreferredCulture = new CultureInfo(PreferredLocale); if (model.Emojis != null) { diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs index ef6d9a14c..75892defb 100644 --- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs +++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs @@ -11,6 +11,16 @@ namespace Discord.Rest { internal static class MessageHelper { + /// + /// Regex used to check if some text is formatted as inline code. + /// + private static readonly Regex InlineCodeRegex = new Regex(@"[^\\]?(`).+?[^\\](`)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + /// + /// Regex used to check if some text is formatted as a code block. + /// + private static readonly Regex BlockCodeRegex = new Regex(@"[^\\]?(```).+?[^\\](```)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + /// Only the author of a message may modify the message. /// Message content is too long, length must be less or equal to . public static async Task ModifyAsync(IMessage msg, BaseDiscordClient client, Action func, @@ -112,9 +122,6 @@ namespace Discord.Rest int index = 0; var codeIndex = 0; - var inlineRegex = new Regex(@"[^\\]?(`).+?[^\\](`)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); - var blockRegex = new Regex(@"[^\\]?(```).+?[^\\](```)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); - // checks if the tag being parsed is wrapped in code blocks bool CheckWrappedCode() { @@ -125,7 +132,7 @@ namespace Discord.Rest // loop through all code blocks that are before the start of the tag while (codeIndex < index) { - var blockMatch = blockRegex.Match(text, codeIndex); + var blockMatch = BlockCodeRegex.Match(text, codeIndex); if (blockMatch.Success) { if (EnclosedInBlock(blockMatch)) @@ -136,7 +143,7 @@ namespace Discord.Rest continue; return false; } - var inlineMatch = inlineRegex.Match(text, codeIndex); + var inlineMatch = InlineCodeRegex.Match(text, codeIndex); if (inlineMatch.Success) { if (EnclosedInBlock(inlineMatch)) diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj index ddd3b7954..26a249097 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj @@ -4,15 +4,12 @@ Discord.Net.WebSocket Discord.WebSocket A core Discord.Net library containing the WebSocket client and models. - net46;netstandard1.3;netstandard2.0 - netstandard1.3;netstandard2.0 + net461;netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1 true - - - diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index cd0ab3db2..054348ef1 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -105,6 +106,11 @@ namespace Discord.WebSocket public string Description { get; private set; } /// public int PremiumSubscriptionCount { get; private set; } + /// + public string PreferredLocale { get; private set; } + + /// + public CultureInfo PreferredCulture { get; private set; } /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); @@ -374,6 +380,8 @@ namespace Discord.WebSocket SystemChannelFlags = model.SystemChannelFlags; Description = model.Description; PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); + PreferredLocale = model.PreferredLocale; + PreferredCulture = new CultureInfo(PreferredLocale); if (model.Emojis != null) { diff --git a/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj b/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj index 58282d85b..f1db66363 100644 --- a/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj +++ b/src/Discord.Net.Webhook/Discord.Net.Webhook.csproj @@ -4,7 +4,7 @@ Discord.Net.Webhook Discord.Webhook A core Discord.Net library containing the Webhook client and models. - netstandard1.3 + netstandard2.0;netstandard2.1 diff --git a/src/Discord.Net/Discord.Net.nuspec b/src/Discord.Net/Discord.Net.nuspec index 3aa0d6add..4b7717e58 100644 --- a/src/Discord.Net/Discord.Net.nuspec +++ b/src/Discord.Net/Discord.Net.nuspec @@ -13,21 +13,21 @@ false https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png - + - - + + - + diff --git a/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj b/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj index 1ee986e8a..bc587657c 100644 --- a/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj +++ b/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.0 false @@ -15,10 +15,13 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs b/test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs deleted file mode 100644 index 729bc385c..000000000 --- a/test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Linq; -using System.Reflection; -using Microsoft.DotNet.PlatformAbstractions; -using Microsoft.Extensions.DependencyModel; - -namespace System -{ - /// Polyfill of the AppDomain class from full framework. - internal class AppDomain - { - public static AppDomain CurrentDomain { get; private set; } - - private AppDomain() - { - } - - static AppDomain() - { - CurrentDomain = new AppDomain(); - } - - public Assembly[] GetAssemblies() - { - var rid = RuntimeEnvironment.GetRuntimeIdentifier(); - var ass = DependencyContext.Default.GetRuntimeAssemblyNames(rid); - - return ass.Select(xan => Assembly.Load(xan)).ToArray(); - } - } -} \ No newline at end of file diff --git a/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj b/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj index cd4aafac0..c571059ef 100644 --- a/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj +++ b/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1 @@ -15,9 +15,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj b/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj index 4a7898b14..357bf9531 100644 --- a/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj +++ b/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj @@ -1,7 +1,7 @@ - + - netcoreapp2.1 + netcoreapp3.0 false @@ -13,9 +13,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs index 573ca57c3..8b4e8b0d0 100644 --- a/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using System.Threading.Tasks; using Discord.Audio;