Browse Source

Merge pull request #4 from discord-net/dev

updating
pull/1414/head
Saulius Šaltenis GitHub 5 years ago
parent
commit
07b3aea4a0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 351 additions and 133 deletions
  1. +7
    -2
      azure-pipelines.yml
  2. +19
    -16
      azure/deploy.yml
  3. +2
    -1
      azure/docs.bat
  4. +2
    -2
      docs/guides/commands/intro.md
  5. +1
    -1
      samples/01_basic_ping_bot/01_basic_ping_bot.csproj
  6. +2
    -2
      samples/02_commands_framework/02_commands_framework.csproj
  7. +5
    -1
      samples/03_sharded_client/03_sharded_client.csproj
  8. +3
    -3
      src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj
  9. +3
    -1
      src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs
  10. +9
    -9
      src/Discord.Net.Commands/CommandService.cs
  11. +3
    -8
      src/Discord.Net.Commands/Discord.Net.Commands.csproj
  12. +1
    -1
      src/Discord.Net.Commands/Readers/UserTypeReader.cs
  13. +4
    -4
      src/Discord.Net.Core/Discord.Net.Core.csproj
  14. +5
    -1
      src/Discord.Net.Core/Entities/Activities/ActivityType.cs
  15. +40
    -0
      src/Discord.Net.Core/Entities/Activities/CustomStatusGame.cs
  16. +20
    -0
      src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs
  17. +19
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  18. +12
    -0
      src/Discord.Net.Core/Entities/Messages/IMessage.cs
  19. +33
    -0
      src/Discord.Net.Core/Entities/Messages/MessageReference.cs
  20. +0
    -4
      src/Discord.Net.Core/Entities/Roles/Color.cs
  21. +1
    -1
      src/Discord.Net.Core/Extensions/AsyncEnumerableExtensions.cs
  22. +11
    -5
      src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs
  23. +2
    -2
      src/Discord.Net.Examples/Discord.Net.Examples.csproj
  24. +2
    -2
      src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj
  25. +1
    -1
      src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs
  26. +6
    -0
      src/Discord.Net.Rest/API/Common/Game.cs
  27. +2
    -0
      src/Discord.Net.Rest/API/Common/Guild.cs
  28. +2
    -0
      src/Discord.Net.Rest/API/Common/Message.cs
  29. +16
    -0
      src/Discord.Net.Rest/API/Common/MessageReference.cs
  30. +2
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs
  31. +3
    -6
      src/Discord.Net.Rest/Discord.Net.Rest.csproj
  32. +6
    -0
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  33. +8
    -0
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  34. +12
    -5
      src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
  35. +13
    -0
      src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
  36. +7
    -0
      src/Discord.Net.Rest/Extensions/EntityExtensions.cs
  37. +2
    -5
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
  38. +8
    -0
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  39. +14
    -0
      src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
  40. +15
    -0
      src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs
  41. +1
    -1
      src/Discord.Net.Webhook/Discord.Net.Webhook.csproj
  42. +4
    -4
      src/Discord.Net/Discord.Net.nuspec
  43. +8
    -5
      test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj
  44. +0
    -30
      test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs
  45. +7
    -4
      test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj
  46. +8
    -5
      test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj
  47. +0
    -1
      test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs

+ 7
- 2
azure-pipelines.yml View File

@@ -16,18 +16,23 @@ jobs:
pool: pool:
vmImage: 'ubuntu-16.04' vmImage: 'ubuntu-16.04'
steps: steps:
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
packageType: 'sdk'
version: '3.x'
- template: azure/build.yml - template: azure/build.yml


- job: Windows_build - job: Windows_build
pool: pool:
vmImage: 'vs2017-win2016'
vmImage: 'windows-2019'
condition: ne(variables['Build.SourceBranch'], 'refs/heads/dev') condition: ne(variables['Build.SourceBranch'], 'refs/heads/dev')
steps: steps:
- template: azure/build.yml - template: azure/build.yml


- job: Windows_deploy - job: Windows_deploy
pool: pool:
vmImage: 'vs2017-win2016'
vmImage: 'windows-2019'
condition: | condition: |
and ( and (
succeeded(), succeeded(),


+ 19
- 16
azure/deploy.yml View File

@@ -1,32 +1,35 @@
steps: steps:
- script: | - 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 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) displayName: Pack metapackage (release mode)
condition: eq(variables['buildTag'], True) condition: eq(variables['buildTag'], True)

- task: NuGet@0
inputs: 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 displayName: Pack metapackage
condition: eq(variables['buildTag'], False) condition: eq(variables['buildTag'], False)
inputs:
command: 'pack'
packagesToPack: 'src/Discord.Net/Discord.Net.nuspec'
versioningScheme: 'off'
buildProperties: 'suffix=-$(buildNumber)'


- task: NuGetCommand@2 - task: NuGetCommand@2
displayName: Push to NuGet displayName: Push to NuGet
inputs: inputs:
command: push command: push
nuGetFeedType: external nuGetFeedType: external
packagesToPush: 'artifacts/*.nupkg'
packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
publishFeedCredentials: myget-discord publishFeedCredentials: myget-discord

+ 2
- 1
azure/docs.bat View File

@@ -5,7 +5,8 @@ ECHO remove old 'latest'
ECHO Y | RMDIR /S docs-static\latest || EXIT /B 1 ECHO Y | RMDIR /S docs-static\latest || EXIT /B 1


ECHO build docs 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 ECHO commit and deploy
git config --global user.name "Discord.Net CI Robot" && git config --global user.email "robot@foxbot.me" git config --global user.name "Discord.Net CI Robot" && git config --global user.email "robot@foxbot.me"


+ 2
- 2
docs/guides/commands/intro.md View File

@@ -111,7 +111,7 @@ optional, give it a default value (i.e., `int num = 0`).


#### Parameters with Spaces #### 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 Should a parameter include spaces, the parameter **must** be
wrapped in quotes. For example, for a command with a parameter 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 submodules are used to create nested groups (although not required to
create nested groups). create nested groups).


[!code-csharp[Groups and Submodules](samples/intro/groups.cs)]
[!code-csharp[Groups and Submodules](samples/intro/groups.cs)]

+ 1
- 1
samples/01_basic_ping_bot/01_basic_ping_bot.csproj View File

@@ -2,7 +2,7 @@


<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>


<ItemGroup> <ItemGroup>


+ 2
- 2
samples/02_commands_framework/02_commands_framework.csproj View File

@@ -2,11 +2,11 @@


<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup> </PropertyGroup>


<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
</ItemGroup> </ItemGroup>


<ItemGroup> <ItemGroup>


+ 5
- 1
samples/03_sharded_client/03_sharded_client.csproj View File

@@ -2,10 +2,14 @@


<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<RootNamespace>_03_sharded_client</RootNamespace> <RootNamespace>_03_sharded_client</RootNamespace>
</PropertyGroup> </PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
</ItemGroup>

<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Discord.Net.Commands\Discord.Net.Commands.csproj" /> <ProjectReference Include="..\..\src\Discord.Net.Commands\Discord.Net.Commands.csproj" />
<ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> <ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" />


+ 3
- 3
src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj View File

@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../Discord.Net.targets" /> <Import Project="../../Discord.Net.targets" />
<PropertyGroup> <PropertyGroup>
<AssemblyName>Discord.Net.Analyzers</AssemblyName> <AssemblyName>Discord.Net.Analyzers</AssemblyName>
<RootNamespace>Discord.Analyzers</RootNamespace> <RootNamespace>Discord.Analyzers</RootNamespace>
<Description>A Discord.Net extension adding support for design-time analysis of the API usage.</Description> <Description>A Discord.Net extension adding support for design-time analysis of the API usage.</Description>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.3.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Commands\Discord.Net.Commands.csproj" /> <ProjectReference Include="..\Discord.Net.Commands\Discord.Net.Commands.csproj" />


+ 3
- 1
src/Discord.Net.Analyzers/GuildAccessAnalyzer.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
@@ -24,6 +24,8 @@ namespace Discord.Analyzers


public override void Initialize(AnalysisContext context) public override void Initialize(AnalysisContext context)
{ {
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.RegisterSyntaxNodeAction(AnalyzeMemberAccess, SyntaxKind.SimpleMemberAccessExpression); context.RegisterSyntaxNodeAction(AnalyzeMemberAccess, SyntaxKind.SimpleMemberAccessExpression);
} }




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

@@ -49,7 +49,7 @@ namespace Discord.Commands
private readonly ConcurrentDictionary<Type, ModuleInfo> _typedModuleDefs; private readonly ConcurrentDictionary<Type, ModuleInfo> _typedModuleDefs;
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>> _typeReaders; private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>> _typeReaders;
private readonly ConcurrentDictionary<Type, TypeReader> _defaultTypeReaders; private readonly ConcurrentDictionary<Type, TypeReader> _defaultTypeReaders;
private readonly ImmutableList<Tuple<Type, Type>> _entityTypeReaders; //TODO: Candidate for C#7 Tuple
private readonly ImmutableList<(Type EntityType, Type TypeReaderType)> _entityTypeReaders;
private readonly HashSet<ModuleInfo> _moduleDefs; private readonly HashSet<ModuleInfo> _moduleDefs;
private readonly CommandMap _map; private readonly CommandMap _map;


@@ -124,11 +124,11 @@ namespace Discord.Commands
_defaultTypeReaders[typeof(string)] = _defaultTypeReaders[typeof(string)] =
new PrimitiveTypeReader<string>((string x, out string y) => { y = x; return true; }, 0); new PrimitiveTypeReader<string>((string x, out string y) => { y = x; return true; }, 0);


var entityTypeReaders = ImmutableList.CreateBuilder<Tuple<Type, Type>>();
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IMessage), typeof(MessageTypeReader<>)));
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IChannel), typeof(ChannelTypeReader<>)));
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IRole), typeof(RoleTypeReader<>)));
entityTypeReaders.Add(new Tuple<Type, Type>(typeof(IUser), typeof(UserTypeReader<>)));
var entityTypeReaders = ImmutableList.CreateBuilder<(Type, Type)>();
entityTypeReaders.Add((typeof(IMessage), typeof(MessageTypeReader<>)));
entityTypeReaders.Add((typeof(IChannel), typeof(ChannelTypeReader<>)));
entityTypeReaders.Add((typeof(IRole), typeof(RoleTypeReader<>)));
entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>)));
_entityTypeReaders = entityTypeReaders.ToImmutable(); _entityTypeReaders = entityTypeReaders.ToImmutable();
} }


@@ -408,7 +408,7 @@ namespace Discord.Commands
var typeInfo = type.GetTypeInfo(); var typeInfo = type.GetTypeInfo();
if (typeInfo.IsEnum) if (typeInfo.IsEnum)
return true; return true;
return _entityTypeReaders.Any(x => type == x.Item1 || typeInfo.ImplementedInterfaces.Contains(x.Item2));
return _entityTypeReaders.Any(x => type == x.EntityType || typeInfo.ImplementedInterfaces.Contains(x.TypeReaderType));
} }
internal void AddNullableTypeReader(Type valueType, TypeReader valueTypeReader) internal void AddNullableTypeReader(Type valueType, TypeReader valueTypeReader)
{ {
@@ -439,9 +439,9 @@ namespace Discord.Commands
//Is this an entity? //Is this an entity?
for (int i = 0; i < _entityTypeReaders.Count; i++) for (int i = 0; i < _entityTypeReaders.Count; i++)
{ {
if (type == _entityTypeReaders[i].Item1 || typeInfo.ImplementedInterfaces.Contains(_entityTypeReaders[i].Item1))
if (type == _entityTypeReaders[i].EntityType || typeInfo.ImplementedInterfaces.Contains(_entityTypeReaders[i].EntityType))
{ {
reader = Activator.CreateInstance(_entityTypeReaders[i].Item2.MakeGenericType(type)) as TypeReader;
reader = Activator.CreateInstance(_entityTypeReaders[i].TypeReaderType.MakeGenericType(type)) as TypeReader;
_defaultTypeReaders[type] = reader; _defaultTypeReaders[type] = reader;
return reader; return reader;
} }


+ 3
- 8
src/Discord.Net.Commands/Discord.Net.Commands.csproj View File

@@ -4,16 +4,11 @@
<AssemblyName>Discord.Net.Commands</AssemblyName> <AssemblyName>Discord.Net.Commands</AssemblyName>
<RootNamespace>Discord.Commands</RootNamespace> <RootNamespace>Discord.Commands</RootNamespace>
<Description>A Discord.Net extension adding support for bot commands.</Description> <Description>A Discord.Net extension adding support for bot commands.</Description>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
</ItemGroup>

</Project> </Project>

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

@@ -49,7 +49,7 @@ namespace Discord.Commands
string username = input.Substring(0, index); string username = input.Substring(0, index);
if (ushort.TryParse(input.Substring(index + 1), out ushort discriminator)) 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); string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false);
AddResult(results, channelUser as T, channelUser?.Username == username ? 0.85f : 0.75f); AddResult(results, channelUser as T, channelUser?.Username == username ? 0.85f : 0.75f);




+ 4
- 4
src/Discord.Net.Core/Discord.Net.Core.csproj View File

@@ -4,13 +4,13 @@
<AssemblyName>Discord.Net.Core</AssemblyName> <AssemblyName>Discord.Net.Core</AssemblyName>
<RootNamespace>Discord</RootNamespace> <RootNamespace>Discord</RootNamespace>
<Description>The core components for the Discord.Net library.</Description> <Description>The core components for the Discord.Net library.</Description>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" /> <PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="System.Interactive.Async" Version="3.2.0" />
<PackageReference Include="System.Interactive.Async" Version="4.0.0" />
<PackageReference Include="IDisposableAnalyzers" Version="2.1.2"> <PackageReference Include="IDisposableAnalyzers" Version="2.1.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>


+ 5
- 1
src/Discord.Net.Core/Entities/Activities/ActivityType.cs View File

@@ -20,6 +20,10 @@ namespace Discord
/// <summary> /// <summary>
/// The user is watching some form of media. /// The user is watching some form of media.
/// </summary> /// </summary>
Watching = 3
Watching = 3,
/// <summary>
/// The user has set a custom status.
/// </summary>
CustomStatus = 4,
} }
} }

+ 40
- 0
src/Discord.Net.Core/Entities/Activities/CustomStatusGame.cs View File

@@ -0,0 +1,40 @@
using System;
using System.Diagnostics;

namespace Discord
{
/// <summary>
/// A user's activity for their custom status.
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class CustomStatusGame : Game
{
internal CustomStatusGame() { }

/// <summary>
/// Gets the emote, if it is set.
/// </summary>
/// <returns>
/// An <see cref="IEmote"/> containing the <see cref="Emoji"/> or <see cref="GuildEmote"/> set by the user.
/// </returns>
public IEmote Emote { get; internal set; }

/// <summary>
/// Gets the timestamp of when this status was created.
/// </summary>
/// <returns>
/// A <see cref="DateTimeOffset"/> containing the time when this status was created.
/// </returns>
public DateTimeOffset CreatedAt { get; internal set; }

/// <summary>
/// Gets the state of the status.
/// </summary>
public string State { get; internal set; }

public override string ToString()
=> $"{Emote} {State}";

private string DebuggerDisplay => $"{Name}";
}
}

+ 20
- 0
src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs View File

@@ -1,3 +1,5 @@
using System.Globalization;

namespace Discord namespace Discord
{ {
/// <summary> /// <summary>
@@ -84,5 +86,23 @@ namespace Discord
/// are enabled, without the need to manipulate the logic of the flag. /// are enabled, without the need to manipulate the logic of the flag.
/// </remarks> /// </remarks>
public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; } public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; }
/// <summary>
/// Gets or sets the preferred locale of the guild in IETF BCP 47 language tag format.
/// </summary>
/// <remarks>
/// This property takes precedence over <see cref="PreferredCulture"/>.
/// When it is set, the value of <see cref="PreferredCulture"/>
/// will not be used.
/// </remarks>
public Optional<string> PreferredLocale { get; set; }
/// <summary>
/// Gets or sets the preferred locale of the guild.
/// </summary>
/// <remarks>
/// The <see cref="PreferredLocale"/> property takes precedence
/// over this property. When <see cref="PreferredLocale"/> is set,
/// the value of <see cref="PreferredCulture"/> will be unused.
/// </remarks>
public Optional<CultureInfo> PreferredCulture { get; set; }
} }
} }

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

@@ -1,6 +1,7 @@
using Discord.Audio; using Discord.Audio;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace Discord namespace Discord
@@ -249,6 +250,24 @@ namespace Discord
/// </returns> /// </returns>
int PremiumSubscriptionCount { get; } int PremiumSubscriptionCount { get; }


/// <summary>
/// Gets the preferred locale of this guild in IETF BCP 47
/// language tag format.
/// </summary>
/// <returns>
/// The preferred locale of the guild in IETF BCP 47
/// language tag format.
/// </returns>
string PreferredLocale { get; }

/// <summary>
/// Gets the preferred culture of this guild.
/// </summary>
/// <returns>
/// The preferred culture information of this guild.
/// </returns>
CultureInfo PreferredCulture { get; }

/// <summary> /// <summary>
/// Modifies this guild. /// Modifies this guild.
/// </summary> /// </summary>


+ 12
- 0
src/Discord.Net.Core/Entities/Messages/IMessage.cs View File

@@ -140,6 +140,18 @@ namespace Discord
/// </returns> /// </returns>
MessageApplication Application { get; } MessageApplication Application { get; }


/// <summary>
/// Gets the reference to the original message if it was crossposted.
/// </summary>
/// <remarks>
/// Sent with Cross-posted messages, meaning they were published from news channels
/// and received by subscriber channels.
/// </remarks>
/// <returns>
/// A message's reference, if any is associated.
/// </returns>
MessageReference Reference { get; }

/// <summary> /// <summary>
/// Gets all reactions included in this message. /// Gets all reactions included in this message.
/// </summary> /// </summary>


+ 33
- 0
src/Discord.Net.Core/Entities/Messages/MessageReference.cs View File

@@ -0,0 +1,33 @@
using System.Diagnostics;

namespace Discord
{
/// <summary>
/// Contains the IDs sent from a crossposted message.
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class MessageReference
{
/// <summary>
/// Gets the Message ID of the original message.
/// </summary>
public Optional<ulong> MessageId { get; internal set; }

/// <summary>
/// Gets the Channel ID of the original message.
/// </summary>
public ulong ChannelId { get; internal set; }

/// <summary>
/// Gets the Guild ID of the original message.
/// </summary>
public Optional<ulong> GuildId { get; internal set; }

private string DebuggerDisplay
=> $"Channel ID: ({ChannelId}){(GuildId.IsSpecified ? $", Guild ID: ({GuildId.Value})" : "")}" +
$"{(MessageId.IsSpecified ? $", Message ID: ({MessageId.Value})" : "")}";

public override string ToString()
=> DebuggerDisplay;
}
}

+ 0
- 4
src/Discord.Net.Core/Entities/Roles/Color.cs View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
#if NETSTANDARD2_0 || NET45
using StandardColor = System.Drawing.Color; using StandardColor = System.Drawing.Color;
#endif


namespace Discord namespace Discord
{ {
@@ -190,12 +188,10 @@ namespace Discord


public override int GetHashCode() => RawValue.GetHashCode(); public override int GetHashCode() => RawValue.GetHashCode();


#if NETSTANDARD2_0 || NET45
public static implicit operator StandardColor(Color color) => public static implicit operator StandardColor(Color color) =>
StandardColor.FromArgb((int)color.RawValue); StandardColor.FromArgb((int)color.RawValue);
public static explicit operator Color(StandardColor color) => public static explicit operator Color(StandardColor color) =>
new Color((uint)color.ToArgb() << 8 >> 8); new Color((uint)color.ToArgb() << 8 >> 8);
#endif


/// <summary> /// <summary>
/// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>). /// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>).


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

@@ -15,7 +15,7 @@ namespace Discord
/// <summary> Flattens the specified pages into one <see cref="IEnumerable{T}"/> asynchronously. </summary> /// <summary> Flattens the specified pages into one <see cref="IEnumerable{T}"/> asynchronously. </summary>
public static async Task<IEnumerable<T>> FlattenAsync<T>(this IAsyncEnumerable<IEnumerable<T>> source) public static async Task<IEnumerable<T>> FlattenAsync<T>(this IAsyncEnumerable<IEnumerable<T>> source)
{ {
return await source.Flatten().ToArray().ConfigureAwait(false);
return await source.Flatten().ToArrayAsync().ConfigureAwait(false);
} }
/// <summary> Flattens the specified pages into one <see cref="IAsyncEnumerable{T}"/>. </summary> /// <summary> Flattens the specified pages into one <see cref="IAsyncEnumerable{T}"/>. </summary>
public static IAsyncEnumerable<T> Flatten<T>(this IAsyncEnumerable<IEnumerable<T>> source) public static IAsyncEnumerable<T> Flatten<T>(this IAsyncEnumerable<IEnumerable<T>> source)


+ 11
- 5
src/Discord.Net.Core/Utils/Paging/PagedEnumerator.cs View File

@@ -25,26 +25,28 @@ namespace Discord
_nextPage = nextPage; _nextPage = nextPage;
} }


public IAsyncEnumerator<IReadOnlyCollection<T>> GetEnumerator() => new Enumerator(this);
public IAsyncEnumerator<IReadOnlyCollection<T>> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken()) => new Enumerator(this, cancellationToken);
internal class Enumerator : IAsyncEnumerator<IReadOnlyCollection<T>> internal class Enumerator : IAsyncEnumerator<IReadOnlyCollection<T>>
{ {
private readonly PagedAsyncEnumerable<T> _source; private readonly PagedAsyncEnumerable<T> _source;
private readonly CancellationToken _token;
private readonly PageInfo _info; private readonly PageInfo _info;


public IReadOnlyCollection<T> Current { get; private set; } public IReadOnlyCollection<T> Current { get; private set; }


public Enumerator(PagedAsyncEnumerable<T> source)
public Enumerator(PagedAsyncEnumerable<T> source, CancellationToken token)
{ {
_source = source; _source = source;
_token = token;
_info = new PageInfo(source._start, source._count, source.PageSize); _info = new PageInfo(source._start, source._count, source.PageSize);
} }


public async Task<bool> MoveNext(CancellationToken cancelToken)
public async ValueTask<bool> MoveNextAsync()
{ {
if (_info.Remaining == 0) if (_info.Remaining == 0)
return false; return false;


var data = await _source._getPage(_info, cancelToken).ConfigureAwait(false);
var data = await _source._getPage(_info, _token).ConfigureAwait(false);
Current = new Page<T>(_info, data); Current = new Page<T>(_info, data);


_info.Page++; _info.Page++;
@@ -71,7 +73,11 @@ namespace Discord
return true; return true;
} }
public void Dispose() { Current = null; }
public ValueTask DisposeAsync()
{
Current = null;
return default;
}
} }
} }
} }

+ 2
- 2
src/Discord.Net.Examples/Discord.Net.Examples.csproj View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
@@ -15,7 +15,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />
<ProjectReference Include="..\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> <ProjectReference Include="..\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" />
<PackageReference Include="JetBrains.Annotations" Version="2018.3.0" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
</ItemGroup> </ItemGroup>


</Project> </Project>

+ 2
- 2
src/Discord.Net.Providers.WS4Net/Discord.Net.Providers.WS4Net.csproj View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../Discord.Net.targets" /> <Import Project="../../Discord.Net.targets" />
<PropertyGroup> <PropertyGroup>
<AssemblyName>Discord.Net.Providers.WS4Net</AssemblyName> <AssemblyName>Discord.Net.Providers.WS4Net</AssemblyName>
<RootNamespace>Discord.Providers.WS4Net</RootNamespace> <RootNamespace>Discord.Providers.WS4Net</RootNamespace>
<Description>An optional WebSocket client provider for Discord.Net using WebSocket4Net</Description> <Description>An optional WebSocket client provider for Discord.Net using WebSocket4Net</Description>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />


+ 1
- 1
src/Discord.Net.Providers.WS4Net/WS4NetProvider.cs View File

@@ -1,4 +1,4 @@
using Discord.Net.WebSockets;
using Discord.Net.WebSockets;


namespace Discord.Net.Providers.WS4Net namespace Discord.Net.Providers.WS4Net
{ {


+ 6
- 0
src/Discord.Net.Rest/API/Common/Game.cs View File

@@ -35,6 +35,12 @@ namespace Discord.API
public Optional<string> SessionId { get; set; } public Optional<string> SessionId { get; set; }
[JsonProperty("Flags")] [JsonProperty("Flags")]
public Optional<ActivityProperties> Flags { get; set; } public Optional<ActivityProperties> Flags { get; set; }
[JsonProperty("id")]
public Optional<string> Id { get; set; }
[JsonProperty("emoji")]
public Optional<Emoji> Emoji { get; set; }
[JsonProperty("created_at")]
public Optional<long> CreatedAt { get; set; }


[OnError] [OnError]
internal void OnError(StreamingContext context, ErrorContext errorContext) internal void OnError(StreamingContext context, ErrorContext errorContext)


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

@@ -58,5 +58,7 @@ namespace Discord.API
public SystemChannelMessageDeny SystemChannelFlags { get; set; } public SystemChannelMessageDeny SystemChannelFlags { get; set; }
[JsonProperty("premium_subscription_count")] [JsonProperty("premium_subscription_count")]
public int? PremiumSubscriptionCount { get; set; } public int? PremiumSubscriptionCount { get; set; }
[JsonProperty("preferred_locale")]
public string PreferredLocale { get; set; }
} }
} }

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

@@ -50,6 +50,8 @@ namespace Discord.API
// sent with Rich Presence-related chat embeds // sent with Rich Presence-related chat embeds
[JsonProperty("application")] [JsonProperty("application")]
public Optional<MessageApplication> Application { get; set; } public Optional<MessageApplication> Application { get; set; }
[JsonProperty("message_reference")]
public Optional<MessageReference> Reference { get; set; }
[JsonProperty("flags")] [JsonProperty("flags")]
public Optional<MessageFlags> Flags { get; set; } public Optional<MessageFlags> Flags { get; set; }
} }


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

@@ -0,0 +1,16 @@
using Newtonsoft.Json;

namespace Discord.API
{
internal class MessageReference
{
[JsonProperty("message_id")]
public Optional<ulong> MessageId { get; set; }

[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }

[JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; }
}
}

+ 2
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs View File

@@ -32,5 +32,7 @@ namespace Discord.API.Rest
public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; } public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; }
[JsonProperty("system_channel_flags")] [JsonProperty("system_channel_flags")]
public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; } public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; }
[JsonProperty("preferred_locale")]
public string PreferredLocale { get; set; }
} }
} }

+ 3
- 6
src/Discord.Net.Rest/Discord.Net.Rest.csproj View File

@@ -4,16 +4,13 @@
<AssemblyName>Discord.Net.Rest</AssemblyName> <AssemblyName>Discord.Net.Rest</AssemblyName>
<RootNamespace>Discord.Rest</RootNamespace> <RootNamespace>Discord.Rest</RootNamespace>
<Description>A core Discord.Net library containing the REST client and models.</Description> <Description>A core Discord.Net library containing the REST client and models.</Description>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<PackageReference Include="System.Net.Http" Version="4.3.3" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
</Project> </Project>

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

@@ -68,6 +68,12 @@ namespace Discord.Rest
if (args.SystemChannelFlags.IsSpecified) if (args.SystemChannelFlags.IsSpecified)
apiArgs.SystemChannelFlags = args.SystemChannelFlags.Value; 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); return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
} }
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>


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

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EmbedModel = Discord.API.GuildEmbed; using EmbedModel = Discord.API.GuildEmbed;
@@ -64,6 +65,11 @@ namespace Discord.Rest
public string Description { get; private set; } public string Description { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public int PremiumSubscriptionCount { get; private set; } public int PremiumSubscriptionCount { get; private set; }
/// <inheritdoc />
public string PreferredLocale { get; private set; }

/// <inheritdoc />
public CultureInfo PreferredCulture { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -124,6 +130,8 @@ namespace Discord.Rest
SystemChannelFlags = model.SystemChannelFlags; SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description; Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();
PreferredLocale = model.PreferredLocale;
PreferredCulture = new CultureInfo(PreferredLocale);


if (model.Emojis != null) if (model.Emojis != null)
{ {


+ 12
- 5
src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs View File

@@ -11,6 +11,16 @@ namespace Discord.Rest
{ {
internal static class MessageHelper internal static class MessageHelper
{ {
/// <summary>
/// Regex used to check if some text is formatted as inline code.
/// </summary>
private static readonly Regex InlineCodeRegex = new Regex(@"[^\\]?(`).+?[^\\](`)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);

/// <summary>
/// Regex used to check if some text is formatted as a code block.
/// </summary>
private static readonly Regex BlockCodeRegex = new Regex(@"[^\\]?(```).+?[^\\](```)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);

/// <exception cref="InvalidOperationException">Only the author of a message may modify the message.</exception> /// <exception cref="InvalidOperationException">Only the author of a message may modify the message.</exception>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public static async Task<Model> ModifyAsync(IMessage msg, BaseDiscordClient client, Action<MessageProperties> func, public static async Task<Model> ModifyAsync(IMessage msg, BaseDiscordClient client, Action<MessageProperties> func,
@@ -112,9 +122,6 @@ namespace Discord.Rest
int index = 0; int index = 0;
var codeIndex = 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 // checks if the tag being parsed is wrapped in code blocks
bool CheckWrappedCode() bool CheckWrappedCode()
{ {
@@ -125,7 +132,7 @@ namespace Discord.Rest
// loop through all code blocks that are before the start of the tag // loop through all code blocks that are before the start of the tag
while (codeIndex < index) while (codeIndex < index)
{ {
var blockMatch = blockRegex.Match(text, codeIndex);
var blockMatch = BlockCodeRegex.Match(text, codeIndex);
if (blockMatch.Success) if (blockMatch.Success)
{ {
if (EnclosedInBlock(blockMatch)) if (EnclosedInBlock(blockMatch))
@@ -136,7 +143,7 @@ namespace Discord.Rest
continue; continue;
return false; return false;
} }
var inlineMatch = inlineRegex.Match(text, codeIndex);
var inlineMatch = InlineCodeRegex.Match(text, codeIndex);
if (inlineMatch.Success) if (inlineMatch.Success)
{ {
if (EnclosedInBlock(inlineMatch)) if (EnclosedInBlock(inlineMatch))


+ 13
- 0
src/Discord.Net.Rest/Entities/Messages/RestMessage.cs View File

@@ -62,6 +62,8 @@ namespace Discord.Rest
public MessageActivity Activity { get; private set; } public MessageActivity Activity { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public MessageApplication Application { get; private set; } public MessageApplication Application { get; private set; }
/// <inheritdoc />
public MessageReference Reference { get; private set; }


internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
: base(discord, id) : base(discord, id)
@@ -108,6 +110,17 @@ namespace Discord.Rest
}; };
} }


if(model.Reference.IsSpecified)
{
// Creates a new Reference from the API model
Reference = new MessageReference
{
GuildId = model.Reference.Value.GuildId,
ChannelId = model.Reference.Value.ChannelId,
MessageId = model.Reference.Value.MessageId
};
}

if (model.Reactions.IsSpecified) if (model.Reactions.IsSpecified)
{ {
var value = model.Reactions.Value; var value = model.Reactions.Value;


+ 7
- 0
src/Discord.Net.Rest/Extensions/EntityExtensions.cs View File

@@ -5,6 +5,13 @@ namespace Discord.Rest
{ {
internal static class EntityExtensions internal static class EntityExtensions
{ {
public static IEmote ToIEmote(this API.Emoji model)
{
if (model.Id.HasValue)
return model.ToEntity();
return new Emoji(model.Name);
}

public static GuildEmote ToEntity(this API.Emoji model) public static GuildEmote ToEntity(this API.Emoji model)
=> new GuildEmote(model.Id.Value, => new GuildEmote(model.Id.Value,
model.Name, model.Name,


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

@@ -4,15 +4,12 @@
<AssemblyName>Discord.Net.WebSocket</AssemblyName> <AssemblyName>Discord.Net.WebSocket</AssemblyName>
<RootNamespace>Discord.WebSocket</RootNamespace> <RootNamespace>Discord.WebSocket</RootNamespace>
<Description>A core Discord.Net library containing the WebSocket client and models.</Description> <Description>A core Discord.Net library containing the WebSocket client and models.</Description>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />
<ProjectReference Include="..\Discord.Net.Rest\Discord.Net.Rest.csproj" /> <ProjectReference Include="..\Discord.Net.Rest\Discord.Net.Rest.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.2" />
</ItemGroup>
</Project> </Project>

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

@@ -5,6 +5,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -105,6 +106,11 @@ namespace Discord.WebSocket
public string Description { get; private set; } public string Description { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public int PremiumSubscriptionCount { get; private set; } public int PremiumSubscriptionCount { get; private set; }
/// <inheritdoc />
public string PreferredLocale { get; private set; }

/// <inheritdoc />
public CultureInfo PreferredCulture { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -374,6 +380,8 @@ namespace Discord.WebSocket
SystemChannelFlags = model.SystemChannelFlags; SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description; Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();
PreferredLocale = model.PreferredLocale;
PreferredCulture = new CultureInfo(PreferredLocale);


if (model.Emojis != null) if (model.Emojis != null)
{ {


+ 14
- 0
src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs View File

@@ -53,6 +53,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public MessageApplication Application { get; private set; } public MessageApplication Application { get; private set; }


/// <inheritdoc />
public MessageReference Reference { get; private set; }

/// <summary> /// <summary>
/// Returns all attachments included in this message. /// Returns all attachments included in this message.
/// </summary> /// </summary>
@@ -140,6 +143,17 @@ namespace Discord.WebSocket
PartyId = model.Activity.Value.PartyId.Value PartyId = model.Activity.Value.PartyId.Value
}; };
} }

if (model.Reference.IsSpecified)
{
// Creates a new Reference from the API model
Reference = new MessageReference
{
GuildId = model.Reference.Value.GuildId,
ChannelId = model.Reference.Value.ChannelId,
MessageId = model.Reference.Value.MessageId
};
}
} }


/// <inheritdoc /> /// <inheritdoc />


+ 15
- 0
src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs View File

@@ -1,3 +1,5 @@
using Discord.Rest;
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;


@@ -7,6 +9,19 @@ namespace Discord.WebSocket
{ {
public static IActivity ToEntity(this API.Game model) public static IActivity ToEntity(this API.Game model)
{ {
// Custom Status Game
if (model.Id.IsSpecified)
{
return new CustomStatusGame()
{
Type = ActivityType.CustomStatus,
Name = model.Name,
State = model.State.IsSpecified ? model.State.Value : null,
Emote = model.Emoji.IsSpecified ? model.Emoji.Value.ToIEmote() : null,
CreatedAt = DateTimeOffset.FromUnixTimeMilliseconds(model.CreatedAt.Value),
};
}

// Spotify Game // Spotify Game
if (model.SyncId.IsSpecified) if (model.SyncId.IsSpecified)
{ {


+ 1
- 1
src/Discord.Net.Webhook/Discord.Net.Webhook.csproj View File

@@ -4,7 +4,7 @@
<AssemblyName>Discord.Net.Webhook</AssemblyName> <AssemblyName>Discord.Net.Webhook</AssemblyName>
<RootNamespace>Discord.Webhook</RootNamespace> <RootNamespace>Discord.Webhook</RootNamespace>
<Description>A core Discord.Net library containing the Webhook client and models.</Description> <Description>A core Discord.Net library containing the Webhook client and models.</Description>
<TargetFrameworks>netstandard1.3</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />


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

@@ -13,21 +13,21 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png</iconUrl> <iconUrl>https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png</iconUrl>
<dependencies> <dependencies>
<group targetFramework="net46">
<group targetFramework="net461">
<dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Commands" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Commands" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Webhook" version="2.2.0-dev$suffix$" />
</group>
<group targetFramework="netstandard1.3">
</group>
<group targetFramework="netstandard2.0">
<dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Commands" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Commands" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Webhook" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Webhook" version="2.2.0-dev$suffix$" />
</group> </group>
<group targetFramework="netstandard2.0">
<group targetFramework="netstandard2.1">
<dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Core" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.Rest" version="2.2.0-dev$suffix$" />
<dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" /> <dependency id="Discord.Net.WebSocket" version="2.2.0-dev$suffix$" />


+ 8
- 5
test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>


<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
@@ -15,10 +15,13 @@
</ItemGroup> </ItemGroup>


<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.0.0-beta4-final" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> </ItemGroup>


</Project> </Project>

+ 0
- 30
test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs View File

@@ -1,30 +0,0 @@
using System.Linq;
using System.Reflection;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.Extensions.DependencyModel;

namespace System
{
/// <summary> Polyfill of the AppDomain class from full framework. </summary>
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();
}
}
}

+ 7
- 4
test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
@@ -15,9 +15,12 @@
</ItemGroup> </ItemGroup>


<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> </ItemGroup>


<ItemGroup> <ItemGroup>


+ 8
- 5
test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>


<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
@@ -13,9 +13,12 @@
<ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> <ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> </ItemGroup>


</Project> </Project>

+ 0
- 1
test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Audio; using Discord.Audio;




Loading…
Cancel
Save