Merge branch 'dev' into feature/reactions
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
@@ -13,9 +14,23 @@ namespace Discord.API
|
||||
public string Description { get; set; }
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
[JsonProperty("color")]
|
||||
public uint? Color { get; set; }
|
||||
[JsonProperty("timestamp")]
|
||||
public DateTimeOffset? Timestamp { get; set; }
|
||||
[JsonProperty("author")]
|
||||
public Optional<EmbedAuthor> Author { get; set; }
|
||||
[JsonProperty("footer")]
|
||||
public Optional<EmbedFooter> Footer { get; set; }
|
||||
[JsonProperty("video")]
|
||||
public Optional<EmbedVideo> Video { get; set; }
|
||||
[JsonProperty("thumbnail")]
|
||||
public Optional<EmbedThumbnail> Thumbnail { get; set; }
|
||||
[JsonProperty("image")]
|
||||
public Optional<EmbedImage> Image { get; set; }
|
||||
[JsonProperty("provider")]
|
||||
public Optional<EmbedProvider> Provider { get; set; }
|
||||
[JsonProperty("fields")]
|
||||
public Optional<EmbedField[]> Fields { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
16
src/Discord.Net.Core/API/Common/EmbedAuthor.cs
Normal file
16
src/Discord.Net.Core/API/Common/EmbedAuthor.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
public class EmbedAuthor
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
[JsonProperty("icon_url")]
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty("proxy_icon_url")]
|
||||
public string ProxyIconUrl { get; set; }
|
||||
}
|
||||
}
|
||||
14
src/Discord.Net.Core/API/Common/EmbedField.cs
Normal file
14
src/Discord.Net.Core/API/Common/EmbedField.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
public class EmbedField
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("value")]
|
||||
public string Value { get; set; }
|
||||
[JsonProperty("inline")]
|
||||
public bool Inline { get; set; }
|
||||
}
|
||||
}
|
||||
14
src/Discord.Net.Core/API/Common/EmbedFooter.cs
Normal file
14
src/Discord.Net.Core/API/Common/EmbedFooter.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
public class EmbedFooter
|
||||
{
|
||||
[JsonProperty("text")]
|
||||
public string Text { get; set; }
|
||||
[JsonProperty("icon_url")]
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty("proxy_icon_url")]
|
||||
public string ProxyIconUrl { get; set; }
|
||||
}
|
||||
}
|
||||
17
src/Discord.Net.Core/API/Common/EmbedImage.cs
Normal file
17
src/Discord.Net.Core/API/Common/EmbedImage.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma warning disable CS1591
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
public class EmbedImage
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
[JsonProperty("proxy_url")]
|
||||
public string ProxyUrl { get; set; }
|
||||
[JsonProperty("height")]
|
||||
public Optional<int> Height { get; set; }
|
||||
[JsonProperty("width")]
|
||||
public Optional<int> Width { get; set; }
|
||||
}
|
||||
}
|
||||
15
src/Discord.Net.Core/API/Common/EmbedVideo.cs
Normal file
15
src/Discord.Net.Core/API/Common/EmbedVideo.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma warning disable CS1591
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
public class EmbedVideo
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
[JsonProperty("height")]
|
||||
public Optional<int> Height { get; set; }
|
||||
[JsonProperty("width")]
|
||||
public Optional<int> Width { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace Discord.API
|
||||
{
|
||||
_restClientProvider = restClientProvider;
|
||||
_userAgent = userAgent;
|
||||
_serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() };
|
||||
_serializer = serializer ?? new JsonSerializer { DateFormatString = "yyyy-MM-ddTHH:mm:ssZ", ContractResolver = new DiscordContractResolver() };
|
||||
RequestQueue = requestQueue;
|
||||
FetchCurrentUser = true;
|
||||
|
||||
@@ -165,30 +165,30 @@ namespace Discord.API
|
||||
|
||||
//Core
|
||||
internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task SendAsync(string method, string endpoint,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null)
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null)
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.HeaderOnly = true;
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var request = new RestRequest(_restClient, method, endpoint, options);
|
||||
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal Task SendJsonAsync(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task SendJsonAsync(string method, string endpoint, object payload,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null)
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null)
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.HeaderOnly = true;
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var json = payload != null ? SerializeJson(payload) : null;
|
||||
var request = new JsonRestRequest(_restClient, method, endpoint, json, options);
|
||||
@@ -196,43 +196,43 @@ namespace Discord.API
|
||||
}
|
||||
|
||||
internal Task SendMultipartAsync(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task SendMultipartAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null)
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null)
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.HeaderOnly = true;
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options);
|
||||
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal Task<TResponse> SendAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class
|
||||
=> SendAsync<TResponse>(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class
|
||||
=> SendAsync<TResponse>(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task<TResponse> SendAsync<TResponse>(string method, string endpoint,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null) where TResponse : class
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var request = new RestRequest(_restClient, method, endpoint, options);
|
||||
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
internal Task<TResponse> SendJsonAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class
|
||||
=> SendJsonAsync<TResponse>(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class
|
||||
=> SendJsonAsync<TResponse>(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task<TResponse> SendJsonAsync<TResponse>(string method, string endpoint, object payload,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null) where TResponse : class
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var json = payload != null ? SerializeJson(payload) : null;
|
||||
var request = new JsonRestRequest(_restClient, method, endpoint, json, options);
|
||||
@@ -240,14 +240,14 @@ namespace Discord.API
|
||||
}
|
||||
|
||||
internal Task<TResponse> SendMultipartAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids,
|
||||
string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendMultipartAsync<TResponse>(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options);
|
||||
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null)
|
||||
=> SendMultipartAsync<TResponse>(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options);
|
||||
public async Task<TResponse> SendMultipartAsync<TResponse>(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs,
|
||||
string bucketId = null, string clientBucketId = null, RequestOptions options = null)
|
||||
string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null)
|
||||
{
|
||||
options = options ?? new RequestOptions();
|
||||
options.BucketId = bucketId;
|
||||
options.ClientBucketId = AuthTokenType == TokenType.User ? clientBucketId : null;
|
||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||
|
||||
var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options);
|
||||
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
||||
@@ -432,20 +432,22 @@ namespace Discord.API
|
||||
if (relativeId != null)
|
||||
endpoint = () => $"channels/{channelId}/messages?limit={limit}&{relativeDir}={relativeId}";
|
||||
else
|
||||
endpoint = () =>$"channels/{channelId}/messages?limit={limit}";
|
||||
endpoint = () => $"channels/{channelId}/messages?limit={limit}";
|
||||
return await SendAsync<IReadOnlyCollection<Message>>("GET", endpoint, ids, options: options).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<Message> CreateMessageAsync(ulong channelId, CreateMessageParams args, RequestOptions options = null)
|
||||
{
|
||||
Preconditions.NotEqual(channelId, 0, nameof(channelId));
|
||||
Preconditions.NotNull(args, nameof(args));
|
||||
Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
|
||||
if (!args.Embed.IsSpecified || args.Embed.Value == null)
|
||||
Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
|
||||
|
||||
if (args.Content.Length > DiscordConfig.MaxMessageSize)
|
||||
throw new ArgumentException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
|
||||
options = RequestOptions.CreateOrClone(options);
|
||||
|
||||
var ids = new BucketIds(channelId: channelId);
|
||||
return await SendJsonAsync<Message>("POST", () => $"channels/{channelId}/messages", args, ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false);
|
||||
return await SendJsonAsync<Message>("POST", () => $"channels/{channelId}/messages", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<Message> UploadFileAsync(ulong channelId, UploadFileParams args, RequestOptions options = null)
|
||||
{
|
||||
@@ -464,7 +466,7 @@ namespace Discord.API
|
||||
}
|
||||
|
||||
var ids = new BucketIds(channelId: channelId);
|
||||
return await SendMultipartAsync<Message>("POST", () => $"channels/{channelId}/messages", args.ToDictionary(), ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false);
|
||||
return await SendMultipartAsync<Message>("POST", () => $"channels/{channelId}/messages", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
|
||||
}
|
||||
public async Task DeleteMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null)
|
||||
{
|
||||
@@ -496,21 +498,22 @@ namespace Discord.API
|
||||
break;
|
||||
}
|
||||
}
|
||||
public async Task<Message> ModifyMessageAsync(ulong channelId, ulong messageId, ModifyMessageParams args, RequestOptions options = null)
|
||||
public async Task<Message> ModifyMessageAsync(ulong channelId, ulong messageId, Rest.ModifyMessageParams args, RequestOptions options = null)
|
||||
{
|
||||
Preconditions.NotEqual(channelId, 0, nameof(channelId));
|
||||
Preconditions.NotEqual(messageId, 0, nameof(messageId));
|
||||
Preconditions.NotNull(args, nameof(args));
|
||||
if (args.Content.IsSpecified)
|
||||
{
|
||||
Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
|
||||
if (!args.Embed.IsSpecified)
|
||||
Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
|
||||
if (args.Content.Value.Length > DiscordConfig.MaxMessageSize)
|
||||
throw new ArgumentOutOfRangeException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
|
||||
}
|
||||
options = RequestOptions.CreateOrClone(options);
|
||||
|
||||
var ids = new BucketIds(channelId: channelId);
|
||||
return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false);
|
||||
return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
|
||||
}
|
||||
public async Task AddReactionAsync(ulong channelId, ulong messageId, string emoji, RequestOptions options = null)
|
||||
{
|
||||
@@ -1112,19 +1115,6 @@ namespace Discord.API
|
||||
using (JsonReader reader = new JsonTextReader(text))
|
||||
return _serializer.Deserialize<T>(reader);
|
||||
}
|
||||
internal string GetBucketId(ulong guildId = 0, ulong channelId = 0, [CallerMemberName] string methodName = "")
|
||||
{
|
||||
if (guildId != 0)
|
||||
{
|
||||
if (channelId != 0)
|
||||
return $"{methodName}({guildId}/{channelId})";
|
||||
else
|
||||
return $"{methodName}({guildId})";
|
||||
}
|
||||
else if (channelId != 0)
|
||||
return $"{methodName}({channelId})";
|
||||
return $"{methodName}()";
|
||||
}
|
||||
|
||||
internal class BucketIds
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Rest
|
||||
@@ -13,6 +14,8 @@ namespace Discord.API.Rest
|
||||
public Optional<string> Nonce { get; set; }
|
||||
[JsonProperty("tts")]
|
||||
public Optional<bool> IsTTS { get; set; }
|
||||
[JsonProperty("embed")]
|
||||
public Optional<Embed> Embed { get; set; }
|
||||
|
||||
public CreateMessageParams(string content)
|
||||
{
|
||||
|
||||
@@ -8,5 +8,7 @@ namespace Discord.API.Rest
|
||||
{
|
||||
[JsonProperty("content")]
|
||||
public Optional<string> Content { get; set; }
|
||||
[JsonProperty("embed")]
|
||||
public Optional<Embed> Embed { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
60
src/Discord.Net.Core/Discord.Net.Core.csproj
Normal file
60
src/Discord.Net.Core/Discord.Net.Core.csproj
Normal file
@@ -0,0 +1,60 @@
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
<PropertyGroup>
|
||||
<Description>A .Net API wrapper and bot framework for Discord.</Description>
|
||||
<VersionPrefix>1.0.0-beta2</VersionPrefix>
|
||||
<TargetFramework>netstandard1.3</TargetFramework>
|
||||
<AssemblyName>Discord.Net.Core</AssemblyName>
|
||||
<PackageTags>discord;discordapp</PackageTags>
|
||||
<PackageProjectUrl>https://github.com/RogueException/Discord.Net</PackageProjectUrl>
|
||||
<PackageLicenseUrl>http://opensource.org/licenses/MIT</PackageLicenseUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>git://github.com/RogueException/Discord.Net</RepositoryUrl>
|
||||
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netstandard1.3' ">$(PackageTargetFallback);dotnet5.4;dnxcore50;portable-net45+win8</PackageTargetFallback>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
<EmbeddedResource Include="**\*.resx" />
|
||||
<EmbeddedResource Include="compiler\resources\**\*" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk">
|
||||
<Version>1.0.0-alpha-20161104-2</Version>
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Win32.Primitives">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>9.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Collections.Concurrent">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Collections.Immutable">
|
||||
<Version>1.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Interactive.Async">
|
||||
<Version>3.1.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Net.Http">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Net.WebSockets.Client">
|
||||
<Version>4.3.0</Version>
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<SignAssembly>False</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
|
||||
<NoWarn>$(NoWarn);CS1573;CS1591</NoWarn>
|
||||
<WarningsAsErrors>true</WarningsAsErrors>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>91e9e7bd-75c9-4e98-84aa-2c271922e5c2</ProjectGuid>
|
||||
<RootNamespace>Discord</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
@@ -11,9 +11,10 @@ namespace Discord
|
||||
"Unknown";
|
||||
|
||||
public static readonly string ClientAPIUrl = $"https://discordapp.com/api/v{APIVersion}/";
|
||||
public const string CDNUrl = "https://discordcdn.com/";
|
||||
public const string CDNUrl = "https://cdn.discordapp.com/";
|
||||
public const string InviteUrl = "https://discord.gg/";
|
||||
|
||||
public const int DefaultRequestTimeout = 15000;
|
||||
public const int MaxMessageSize = 2000;
|
||||
public const int MaxMessagesPerBatch = 100;
|
||||
public const int MaxUsersPerBatch = 1000;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Discord
|
||||
public interface IMessageChannel : IChannel
|
||||
{
|
||||
/// <summary> Sends a message to this message channel. </summary>
|
||||
Task<IUserMessage> SendMessageAsync(string text, bool isTTS = false, RequestOptions options = null);
|
||||
Task<IUserMessage> SendMessageAsync(string text, bool isTTS = false, EmbedBuilder embed = null, RequestOptions options = null);
|
||||
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
|
||||
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, RequestOptions options = null);
|
||||
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
|
||||
|
||||
29
src/Discord.Net.Core/Entities/Messages/EmbedAuthor.cs
Normal file
29
src/Discord.Net.Core/Entities/Messages/EmbedAuthor.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.EmbedAuthor;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public struct EmbedAuthor
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string IconUrl { get; set; }
|
||||
public string ProxyIconUrl { get; set; }
|
||||
|
||||
private EmbedAuthor(string name, string url, string iconUrl, string proxyIconUrl)
|
||||
{
|
||||
Name = name;
|
||||
Url = url;
|
||||
IconUrl = iconUrl;
|
||||
ProxyIconUrl = proxyIconUrl;
|
||||
}
|
||||
internal static EmbedAuthor Create(Model model)
|
||||
{
|
||||
return new EmbedAuthor(model.Name, model.Url, model.IconUrl, model.ProxyIconUrl);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Name} ({Url})";
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
208
src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs
Normal file
208
src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Embed = Discord.API.Embed;
|
||||
using Field = Discord.API.EmbedField;
|
||||
using Author = Discord.API.EmbedAuthor;
|
||||
using Footer = Discord.API.EmbedFooter;
|
||||
using Thumbnail = Discord.API.EmbedThumbnail;
|
||||
using Image = Discord.API.EmbedImage;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class EmbedBuilder
|
||||
{
|
||||
private readonly Embed _model;
|
||||
private readonly List<Field> _fields;
|
||||
|
||||
public EmbedBuilder()
|
||||
{
|
||||
_model = new Embed { Type = "rich" };
|
||||
_fields = new List<Field>();
|
||||
}
|
||||
|
||||
public string Title { get { return _model.Title; } set { _model.Title = value; } }
|
||||
public string Description { get { return _model.Description; } set { _model.Description = value; } }
|
||||
public string Url { get { return _model.Url; } set { _model.Url = value; } }
|
||||
public string ThumbnailUrl { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
public DateTimeOffset? Timestamp { get; set; }
|
||||
public Color? Color { get { return _model.Color.HasValue ? new Color(_model.Color.Value) : (Color?)null; } set { _model.Color = value?.RawValue; } }
|
||||
public EmbedAuthorBuilder Author { get; set; }
|
||||
public EmbedFooterBuilder Footer { get; set; }
|
||||
|
||||
public EmbedBuilder WithTitle(string title)
|
||||
{
|
||||
Title = title;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithDescription(string description)
|
||||
{
|
||||
Description = description;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithUrl(string url)
|
||||
{
|
||||
Url = url;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithThumbnailUrl(string thumbnailUrl)
|
||||
{
|
||||
ThumbnailUrl = thumbnailUrl;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithImageUrl(string imageUrl)
|
||||
{
|
||||
ImageUrl = ImageUrl;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithCurrentTimestamp()
|
||||
{
|
||||
Timestamp = DateTimeOffset.UtcNow;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithTimestamp(DateTimeOffset dateTimeOffset)
|
||||
{
|
||||
Timestamp = dateTimeOffset;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithColor(Color color)
|
||||
{
|
||||
Color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedBuilder WithAuthor(EmbedAuthorBuilder author)
|
||||
{
|
||||
Author = author;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithAuthor(Action<EmbedAuthorBuilder> action)
|
||||
{
|
||||
var author = new EmbedAuthorBuilder();
|
||||
action(author);
|
||||
Author = author;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithFooter(EmbedFooterBuilder footer)
|
||||
{
|
||||
Footer = footer;
|
||||
return this;
|
||||
}
|
||||
public EmbedBuilder WithFooter(Action<EmbedFooterBuilder> action)
|
||||
{
|
||||
var footer = new EmbedFooterBuilder();
|
||||
action(footer);
|
||||
Footer = footer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedBuilder AddField(Action<EmbedFieldBuilder> action)
|
||||
{
|
||||
var field = new EmbedFieldBuilder();
|
||||
action(field);
|
||||
_fields.Add(field.ToModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
internal Embed Build()
|
||||
{
|
||||
_model.Author = Author?.ToModel();
|
||||
_model.Footer = Footer?.ToModel();
|
||||
_model.Timestamp = Timestamp?.ToUniversalTime();
|
||||
_model.Thumbnail = ThumbnailUrl != null ? new Thumbnail { Url = ThumbnailUrl } : null;
|
||||
_model.Image = ImageUrl != null ? new Image { Url = ImageUrl } : null;
|
||||
_model.Fields = _fields.ToArray();
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
|
||||
public class EmbedFieldBuilder
|
||||
{
|
||||
private readonly Field _model;
|
||||
|
||||
public string Name { get { return _model.Name; } set { _model.Name = value; } }
|
||||
public string Value { get { return _model.Value; } set { _model.Value = value; } }
|
||||
public bool IsInline { get { return _model.Inline; } set { _model.Inline = value; } }
|
||||
|
||||
public EmbedFieldBuilder()
|
||||
{
|
||||
_model = new Field();
|
||||
}
|
||||
|
||||
public EmbedFieldBuilder WithName(string name)
|
||||
{
|
||||
Name = name;
|
||||
return this;
|
||||
}
|
||||
public EmbedFieldBuilder WithValue(string value)
|
||||
{
|
||||
Value = value;
|
||||
return this;
|
||||
}
|
||||
public EmbedFieldBuilder WithIsInline(bool isInline)
|
||||
{
|
||||
IsInline = isInline;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal Field ToModel() => _model;
|
||||
}
|
||||
|
||||
public class EmbedAuthorBuilder
|
||||
{
|
||||
private readonly Author _model;
|
||||
|
||||
public string Name { get { return _model.Name; } set { _model.Name = value; } }
|
||||
public string Url { get { return _model.Url; } set { _model.Url = value; } }
|
||||
public string IconUrl { get { return _model.IconUrl; } set { _model.IconUrl = value; } }
|
||||
|
||||
public EmbedAuthorBuilder()
|
||||
{
|
||||
_model = new Author();
|
||||
}
|
||||
|
||||
public EmbedAuthorBuilder WithName(string name)
|
||||
{
|
||||
Name = name;
|
||||
return this;
|
||||
}
|
||||
public EmbedAuthorBuilder WithUrl(string url)
|
||||
{
|
||||
Url = url;
|
||||
return this;
|
||||
}
|
||||
public EmbedAuthorBuilder WithIconUrl(string iconUrl)
|
||||
{
|
||||
IconUrl = iconUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal Author ToModel() => _model;
|
||||
}
|
||||
|
||||
public class EmbedFooterBuilder
|
||||
{
|
||||
private readonly Footer _model;
|
||||
|
||||
public string Text { get { return _model.Text; } set { _model.Text = value; } }
|
||||
public string IconUrl { get { return _model.IconUrl; } set { _model.IconUrl = value; } }
|
||||
|
||||
public EmbedFooterBuilder()
|
||||
{
|
||||
_model = new Footer();
|
||||
}
|
||||
|
||||
public EmbedFooterBuilder WithText(string text)
|
||||
{
|
||||
Text = text;
|
||||
return this;
|
||||
}
|
||||
public EmbedFooterBuilder WithIconUrl(string iconUrl)
|
||||
{
|
||||
IconUrl = iconUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal Footer ToModel() => _model;
|
||||
}
|
||||
}
|
||||
27
src/Discord.Net.Core/Entities/Messages/EmbedField.cs
Normal file
27
src/Discord.Net.Core/Entities/Messages/EmbedField.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.EmbedField;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public struct EmbedField
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool Inline { get; set; }
|
||||
|
||||
private EmbedField(string name, string value, bool inline)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
Inline = inline;
|
||||
}
|
||||
internal static EmbedField Create(Model model)
|
||||
{
|
||||
return new EmbedField(model.Name, model.Value, model.Inline);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Name} ({Value}";
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
27
src/Discord.Net.Core/Entities/Messages/EmbedFooter.cs
Normal file
27
src/Discord.Net.Core/Entities/Messages/EmbedFooter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.EmbedFooter;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public struct EmbedFooter
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public string IconUrl { get; set; }
|
||||
public string ProxyUrl { get; set; }
|
||||
|
||||
private EmbedFooter(string text, string iconUrl, string proxyUrl)
|
||||
{
|
||||
Text = text;
|
||||
IconUrl = iconUrl;
|
||||
ProxyUrl = proxyUrl;
|
||||
}
|
||||
internal static EmbedFooter Create(Model model)
|
||||
{
|
||||
return new EmbedFooter(model.Text, model.IconUrl, model.ProxyIconUrl);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Text} ({IconUrl})";
|
||||
public override string ToString() => Text;
|
||||
}
|
||||
}
|
||||
31
src/Discord.Net.Core/Entities/Messages/EmbedImage.cs
Normal file
31
src/Discord.Net.Core/Entities/Messages/EmbedImage.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.EmbedImage;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public struct EmbedImage
|
||||
{
|
||||
public string Url { get; }
|
||||
public string ProxyUrl { get; }
|
||||
public int? Height { get; }
|
||||
public int? Width { get; }
|
||||
|
||||
private EmbedImage(string url, string proxyUrl, int? height, int? width)
|
||||
{
|
||||
Url = url;
|
||||
ProxyUrl = proxyUrl;
|
||||
Height = height;
|
||||
Width = width;
|
||||
}
|
||||
internal static EmbedImage Create(Model model)
|
||||
{
|
||||
return new EmbedImage(model.Url, model.ProxyUrl,
|
||||
model.Height.IsSpecified ? model.Height.Value : (int?)null,
|
||||
model.Width.IsSpecified ? model.Width.Value : (int?)null);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||
public override string ToString() => Url;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Discord
|
||||
model.Width.IsSpecified ? model.Width.Value : (int?)null);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{ToString()} ({Url})";
|
||||
public override string ToString() => Width != null && Height != null ? $"{Width}x{Height}" : "0x0";
|
||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||
public override string ToString() => Url;
|
||||
}
|
||||
}
|
||||
|
||||
29
src/Discord.Net.Core/Entities/Messages/EmbedVideo.cs
Normal file
29
src/Discord.Net.Core/Entities/Messages/EmbedVideo.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.EmbedVideo;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public struct EmbedVideo
|
||||
{
|
||||
public string Url { get; }
|
||||
public int? Height { get; }
|
||||
public int? Width { get; }
|
||||
|
||||
private EmbedVideo(string url, int? height, int? width)
|
||||
{
|
||||
Url = url;
|
||||
Height = height;
|
||||
Width = width;
|
||||
}
|
||||
internal static EmbedVideo Create(Model model)
|
||||
{
|
||||
return new EmbedVideo(model.Url,
|
||||
model.Height.IsSpecified ? model.Height.Value : (int?)null,
|
||||
model.Width.IsSpecified ? model.Width.Value : (int?)null);
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||
public override string ToString() => Url;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace Discord
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public interface IEmbed
|
||||
{
|
||||
@@ -6,7 +9,14 @@
|
||||
string Type { get; }
|
||||
string Title { get; }
|
||||
string Description { get; }
|
||||
DateTimeOffset? Timestamp { get; }
|
||||
Color? Color { get; }
|
||||
EmbedImage? Image { get; }
|
||||
EmbedVideo? Video { get; }
|
||||
EmbedAuthor? Author { get; }
|
||||
EmbedFooter? Footer { get; }
|
||||
EmbedProvider? Provider { get; }
|
||||
EmbedThumbnail? Thumbnail { get; }
|
||||
ImmutableArray<EmbedField> Fields { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.API.Rest;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class ModifyMessageParams
|
||||
{
|
||||
public Optional<string> Content { get; set; }
|
||||
public Optional<EmbedBuilder> Embed { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,12 @@
|
||||
{
|
||||
public enum TagHandling
|
||||
{
|
||||
Ignore = 0,
|
||||
Remove,
|
||||
Name,
|
||||
FullName,
|
||||
Sanitize
|
||||
Ignore = 0, //<@53905483156684800> -> <@53905483156684800>
|
||||
Remove, //<@53905483156684800> ->
|
||||
Name, //<@53905483156684800> -> @Voltana
|
||||
NameNoPrefix, //<@53905483156684800> -> Voltana
|
||||
FullName, //<@53905483156684800> -> @Voltana#8252
|
||||
FullNameNoPrefix, //<@53905483156684800> -> Voltana#8252
|
||||
Sanitize //<@53905483156684800> -> <@53905483156684800> (w/ nbsp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace Discord
|
||||
}
|
||||
public Color(float r, float g, float b)
|
||||
{
|
||||
if (r < 0.0f || r > 1.0f)
|
||||
throw new ArgumentOutOfRangeException(nameof(r), "A float value must be within [0,1]");
|
||||
if (g < 0.0f || g > 1.0f)
|
||||
throw new ArgumentOutOfRangeException(nameof(g), "A float value must be within [0,1]");
|
||||
if (b < 0.0f || b > 1.0f)
|
||||
throw new ArgumentOutOfRangeException(nameof(b), "A float value must be within [0,1]");
|
||||
RawValue =
|
||||
((uint)(r * 255.0f) << 16) |
|
||||
((uint)(g * 255.0f) << 8) |
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public interface IRole : ISnowflakeEntity, IDeletable, IMentionable
|
||||
public interface IRole : ISnowflakeEntity, IDeletable, IMentionable, IComparable<IRole>
|
||||
{
|
||||
/// <summary> Gets the guild owning this role.</summary>
|
||||
IGuild Guild { get; }
|
||||
@@ -27,4 +27,4 @@ namespace Discord
|
||||
///// <summary> Modifies this role. </summary>
|
||||
Task ModifyAsync(Action<ModifyGuildRoleParams> func, RequestOptions options = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,23 @@ namespace Discord
|
||||
{
|
||||
public static class GuildUserExtensions
|
||||
{
|
||||
//TODO: Should we remove Add/Remove? Encourages race conditions.
|
||||
public static Task AddRolesAsync(this IGuildUser user, params IRole[] roles)
|
||||
=> AddRolesAsync(user, (IEnumerable<IRole>)roles);
|
||||
=> ChangeRolesAsync(user, add: roles);
|
||||
public static Task AddRolesAsync(this IGuildUser user, IEnumerable<IRole> roles)
|
||||
=> user.ModifyAsync(x => x.RoleIds = user.RoleIds.Concat(roles.Select(y => y.Id)).ToArray());
|
||||
|
||||
=> ChangeRolesAsync(user, add: roles);
|
||||
public static Task RemoveRolesAsync(this IGuildUser user, params IRole[] roles)
|
||||
=> RemoveRolesAsync(user, (IEnumerable<IRole>)roles);
|
||||
=> ChangeRolesAsync(user, remove: roles);
|
||||
public static Task RemoveRolesAsync(this IGuildUser user, IEnumerable<IRole> roles)
|
||||
=> user.ModifyAsync(x => x.RoleIds = user.RoleIds.Except(roles.Select(y => y.Id)).ToArray());
|
||||
=> ChangeRolesAsync(user, remove: roles);
|
||||
public static async Task ChangeRolesAsync(this IGuildUser user, IEnumerable<IRole> add = null, IEnumerable<IRole> remove = null)
|
||||
{
|
||||
IEnumerable<ulong> roleIds = user.RoleIds;
|
||||
if (remove != null)
|
||||
roleIds = roleIds.Except(remove.Select(x => x.Id));
|
||||
if (add != null)
|
||||
roleIds = roleIds.Concat(add.Select(x => x.Id));
|
||||
await user.ModifyAsync(x => x.RoleIds = roleIds.ToArray()).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
src/Discord.Net.Core/Extensions/RoleExtensions.cs
Normal file
18
src/Discord.Net.Core/Extensions/RoleExtensions.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Discord
|
||||
{
|
||||
internal static class RoleExtensions
|
||||
{
|
||||
internal static int Compare(this IRole left, IRole right)
|
||||
{
|
||||
if (left == null)
|
||||
return -1;
|
||||
if (right == null)
|
||||
return 1;
|
||||
var result = left.Position.CompareTo(right.Position);
|
||||
// As per Discord's documentation, a tie is broken by ID
|
||||
if (result != 0)
|
||||
return result;
|
||||
return left.Id.CompareTo(right.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,47 @@
|
||||
|
||||
namespace Discord.Net.Queue
|
||||
{
|
||||
public struct ClientBucket
|
||||
public enum ClientBucketType
|
||||
{
|
||||
public const string SendEditId = "<send_edit>";
|
||||
Unbucketed = 0,
|
||||
SendEdit = 1
|
||||
}
|
||||
internal struct ClientBucket
|
||||
{
|
||||
private static readonly ImmutableDictionary<ClientBucketType, ClientBucket> _defsByType;
|
||||
private static readonly ImmutableDictionary<string, ClientBucket> _defsById;
|
||||
|
||||
private static readonly ImmutableDictionary<string, ClientBucket> _defs;
|
||||
static ClientBucket()
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, ClientBucket>();
|
||||
builder.Add(SendEditId, new ClientBucket(10, 10));
|
||||
_defs = builder.ToImmutable();
|
||||
var buckets = new[]
|
||||
{
|
||||
new ClientBucket(ClientBucketType.Unbucketed, "<unbucketed>", 10, 10),
|
||||
new ClientBucket(ClientBucketType.SendEdit, "<send_edit>", 10, 10)
|
||||
};
|
||||
|
||||
var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>();
|
||||
foreach (var bucket in buckets)
|
||||
builder.Add(bucket.Type, bucket);
|
||||
_defsByType = builder.ToImmutable();
|
||||
|
||||
var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>();
|
||||
foreach (var bucket in buckets)
|
||||
builder2.Add(bucket.Id, bucket);
|
||||
_defsById = builder2.ToImmutable();
|
||||
}
|
||||
|
||||
public static ClientBucket Get(string id) =>_defs[id];
|
||||
|
||||
public static ClientBucket Get(ClientBucketType type) => _defsByType[type];
|
||||
public static ClientBucket Get(string id) => _defsById[id];
|
||||
|
||||
public ClientBucketType Type { get; }
|
||||
public string Id { get; }
|
||||
public int WindowCount { get; }
|
||||
public int WindowSeconds { get; }
|
||||
|
||||
public ClientBucket(int count, int seconds)
|
||||
public ClientBucket(ClientBucketType type, string id, int count, int seconds)
|
||||
{
|
||||
Type = type;
|
||||
Id = id;
|
||||
WindowCount = count;
|
||||
WindowSeconds = seconds;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,9 @@ namespace Discord.Net.Queue
|
||||
int millis = (int)Math.Ceiling((_waitUntil - DateTimeOffset.UtcNow).TotalMilliseconds);
|
||||
if (millis > 0)
|
||||
{
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Sleeping {millis} ms (Pre-emptive) [Global]");
|
||||
#endif
|
||||
await Task.Delay(millis).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
using Discord.Net.Rest;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
#if DEBUG_LIMITS
|
||||
using System.Diagnostics;
|
||||
#endif
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
@@ -27,8 +30,8 @@ namespace Discord.Net.Queue
|
||||
|
||||
_lock = new object();
|
||||
|
||||
if (request.Options.ClientBucketId != null)
|
||||
WindowCount = ClientBucket.Get(request.Options.ClientBucketId).WindowCount;
|
||||
if (request.Options.IsClientBucket)
|
||||
WindowCount = ClientBucket.Get(request.Options.BucketId).WindowCount;
|
||||
else
|
||||
WindowCount = 1; //Only allow one request until we get a header back
|
||||
_semaphore = WindowCount;
|
||||
@@ -40,62 +43,91 @@ namespace Discord.Net.Queue
|
||||
public async Task<Stream> SendAsync(RestRequest request)
|
||||
{
|
||||
int id = Interlocked.Increment(ref nextId);
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Start");
|
||||
#endif
|
||||
LastAttemptAt = DateTimeOffset.UtcNow;
|
||||
while (true)
|
||||
{
|
||||
await _queue.EnterGlobalAsync(id, request).ConfigureAwait(false);
|
||||
await EnterAsync(id, request).ConfigureAwait(false);
|
||||
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Sending...");
|
||||
var response = await request.SendAsync().ConfigureAwait(false);
|
||||
TimeSpan lag = DateTimeOffset.UtcNow - DateTimeOffset.Parse(response.Headers["Date"]);
|
||||
var info = new RateLimitInfo(response.Headers);
|
||||
|
||||
if (response.StatusCode < (HttpStatusCode)200 || response.StatusCode >= (HttpStatusCode)300)
|
||||
#endif
|
||||
TimeSpan lag = default(TimeSpan);
|
||||
RateLimitInfo info = default(RateLimitInfo);
|
||||
try
|
||||
{
|
||||
switch (response.StatusCode)
|
||||
var response = await request.SendAsync().ConfigureAwait(false);
|
||||
lag = DateTimeOffset.UtcNow - DateTimeOffset.Parse(response.Headers["Date"]);
|
||||
info = new RateLimitInfo(response.Headers);
|
||||
|
||||
if (response.StatusCode < (HttpStatusCode)200 || response.StatusCode >= (HttpStatusCode)300)
|
||||
{
|
||||
case (HttpStatusCode)429:
|
||||
if (info.IsGlobal)
|
||||
{
|
||||
Debug.WriteLine($"[{id}] (!) 429 [Global]");
|
||||
_queue.PauseGlobal(info, lag);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"[{id}] (!) 429");
|
||||
UpdateRateLimit(id, request, info, lag, true);
|
||||
}
|
||||
await _queue.RaiseRateLimitTriggered(Id, info).ConfigureAwait(false);
|
||||
continue; //Retry
|
||||
case HttpStatusCode.BadGateway: //502
|
||||
Debug.WriteLine($"[{id}] (!) 502");
|
||||
continue; //Continue
|
||||
default:
|
||||
string reason = null;
|
||||
if (response.Stream != null)
|
||||
{
|
||||
try
|
||||
switch (response.StatusCode)
|
||||
{
|
||||
case (HttpStatusCode)429:
|
||||
if (info.IsGlobal)
|
||||
{
|
||||
using (var reader = new StreamReader(response.Stream))
|
||||
using (var jsonReader = new JsonTextReader(reader))
|
||||
{
|
||||
var json = JToken.Load(jsonReader);
|
||||
reason = json.Value<string>("message");
|
||||
}
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] (!) 429 [Global]");
|
||||
#endif
|
||||
_queue.PauseGlobal(info, lag);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
throw new HttpException(response.StatusCode, reason);
|
||||
else
|
||||
{
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] (!) 429");
|
||||
#endif
|
||||
UpdateRateLimit(id, request, info, lag, true);
|
||||
}
|
||||
await _queue.RaiseRateLimitTriggered(Id, info).ConfigureAwait(false);
|
||||
continue; //Retry
|
||||
case HttpStatusCode.BadGateway: //502
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] (!) 502");
|
||||
#endif
|
||||
continue; //Continue
|
||||
default:
|
||||
string reason = null;
|
||||
if (response.Stream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(response.Stream))
|
||||
using (var jsonReader = new JsonTextReader(reader))
|
||||
{
|
||||
var json = JToken.Load(jsonReader);
|
||||
reason = json.Value<string>("message");
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
throw new HttpException(response.StatusCode, reason);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Success");
|
||||
#endif
|
||||
return response.Stream;
|
||||
}
|
||||
}
|
||||
else
|
||||
#if DEBUG_LIMITS
|
||||
catch
|
||||
{
|
||||
Debug.WriteLine($"[{id}] Error");
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
finally
|
||||
{
|
||||
Debug.WriteLine($"[{id}] Success");
|
||||
UpdateRateLimit(id, request, info, lag, false);
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Stop");
|
||||
return response.Stream;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +167,9 @@ namespace Discord.Net.Queue
|
||||
if (resetAt > timeoutAt)
|
||||
throw new RateLimitedException();
|
||||
int millis = (int)Math.Ceiling((resetAt.Value - DateTimeOffset.UtcNow).TotalMilliseconds);
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Sleeping {millis} ms (Pre-emptive)");
|
||||
#endif
|
||||
if (millis > 0)
|
||||
await Task.Delay(millis, request.CancelToken).ConfigureAwait(false);
|
||||
}
|
||||
@@ -143,13 +177,17 @@ namespace Discord.Net.Queue
|
||||
{
|
||||
if ((timeoutAt.Value - DateTimeOffset.UtcNow).TotalMilliseconds < 500.0)
|
||||
throw new RateLimitedException();
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Sleeping 500* ms (Pre-emptive)");
|
||||
#endif
|
||||
await Task.Delay(500, request.CancelToken).ConfigureAwait(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#if DEBUG_LIMITS
|
||||
else
|
||||
Debug.WriteLine($"[{id}] Entered Semaphore ({_semaphore}/{WindowCount} remaining)");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +204,9 @@ namespace Discord.Net.Queue
|
||||
{
|
||||
WindowCount = info.Limit.Value;
|
||||
_semaphore = info.Remaining.Value;
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Upgraded Semaphore to {info.Remaining.Value}/{WindowCount}");
|
||||
#endif
|
||||
}
|
||||
|
||||
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
@@ -182,24 +222,32 @@ namespace Discord.Net.Queue
|
||||
{
|
||||
//RetryAfter is more accurate than Reset, where available
|
||||
resetTick = DateTimeOffset.UtcNow.AddMilliseconds(info.RetryAfter.Value);
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Retry-After: {info.RetryAfter.Value} ({info.RetryAfter.Value} ms)");
|
||||
#endif
|
||||
}
|
||||
else if (info.Reset.HasValue)
|
||||
{
|
||||
resetTick = info.Reset.Value.AddSeconds(/*1.0 +*/ lag.TotalSeconds);
|
||||
int diff = (int)(resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds;
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {lag.TotalMilliseconds} ms lag)");
|
||||
#endif
|
||||
}
|
||||
else if (request.Options.ClientBucketId != null)
|
||||
else if (request.Options.IsClientBucket && request.Options.BucketId != null)
|
||||
{
|
||||
resetTick = DateTimeOffset.UtcNow.AddSeconds(ClientBucket.Get(request.Options.ClientBucketId).WindowSeconds);
|
||||
Debug.WriteLine($"[{id}] Client Bucket ({ClientBucket.Get(request.Options.ClientBucketId).WindowSeconds * 1000} ms)");
|
||||
resetTick = DateTimeOffset.UtcNow.AddSeconds(ClientBucket.Get(request.Options.BucketId).WindowSeconds);
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Client Bucket ({ClientBucket.Get(request.Options.BucketId).WindowSeconds * 1000} ms)");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (resetTick == null)
|
||||
{
|
||||
WindowCount = 0; //No rate limit info, disable limits on this bucket (should only ever happen with a user token)
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Disabled Semaphore");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -207,7 +255,9 @@ namespace Discord.Net.Queue
|
||||
{
|
||||
_resetTick = resetTick;
|
||||
LastAttemptAt = resetTick.Value; //Make sure we dont destroy this until after its been reset
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] Reset in {(int)Math.Ceiling((resetTick - DateTimeOffset.UtcNow).Value.TotalMilliseconds)} ms");
|
||||
#endif
|
||||
|
||||
if (!hasQueuedReset)
|
||||
{
|
||||
@@ -227,7 +277,9 @@ namespace Discord.Net.Queue
|
||||
millis = (int)Math.Ceiling((_resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds);
|
||||
if (millis <= 0) //Make sure we havent gotten a more accurate reset time
|
||||
{
|
||||
#if DEBUG_LIMITS
|
||||
Debug.WriteLine($"[{id}] * Reset *");
|
||||
#endif
|
||||
_semaphore = WindowCount;
|
||||
_resetTick = null;
|
||||
return;
|
||||
@@ -236,4 +288,4 @@ namespace Discord.Net.Queue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace Discord.Net.Rest
|
||||
cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelToken, cancelToken).Token;
|
||||
HttpResponseMessage response = await _client.SendAsync(request, cancelToken).ConfigureAwait(false);
|
||||
|
||||
var headers = response.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault());
|
||||
var headers = response.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase);
|
||||
var stream = !headerOnly ? await response.Content.ReadAsStreamAsync().ConfigureAwait(false) : null;
|
||||
|
||||
return new RestResponse(response.StatusCode, headers, stream);
|
||||
|
||||
@@ -101,6 +101,8 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
if (_client != null && _client.State == WebSocketState.Open)
|
||||
{
|
||||
var token = new CancellationToken();
|
||||
await _client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", token);
|
||||
_client.Dispose();
|
||||
_client = null;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
internal bool IgnoreState { get; set; }
|
||||
internal string BucketId { get; set; }
|
||||
internal string ClientBucketId { get; set; }
|
||||
internal bool IsClientBucket { get; set; }
|
||||
|
||||
internal static RequestOptions CreateOrClone(RequestOptions options)
|
||||
{
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
public RequestOptions()
|
||||
{
|
||||
Timeout = 30000;
|
||||
Timeout = DiscordConfig.DefaultRequestTimeout;
|
||||
}
|
||||
|
||||
public RequestOptions Clone() => MemberwiseClone() as RequestOptions;
|
||||
|
||||
@@ -85,14 +85,17 @@ namespace Discord
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static string Resolve(IMessage msg, TagHandling userHandling, TagHandling channelHandling, TagHandling roleHandling, TagHandling everyoneHandling, TagHandling emojiHandling)
|
||||
internal static string Resolve(IMessage msg, int startIndex, TagHandling userHandling, TagHandling channelHandling, TagHandling roleHandling, TagHandling everyoneHandling, TagHandling emojiHandling)
|
||||
{
|
||||
var text = new StringBuilder(msg.Content);
|
||||
var text = new StringBuilder(msg.Content.Substring(startIndex));
|
||||
var tags = msg.Tags;
|
||||
int indexOffset = 0;
|
||||
int indexOffset = -startIndex;
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
if (tag.Index < startIndex)
|
||||
continue;
|
||||
|
||||
string newText = "";
|
||||
switch (tag.Type)
|
||||
{
|
||||
@@ -139,12 +142,22 @@ namespace Discord
|
||||
if (user != null)
|
||||
return $"@{guildUser?.Nickname ?? user?.Username}";
|
||||
else
|
||||
return $"@unknown-user";
|
||||
return $"";
|
||||
case TagHandling.NameNoPrefix:
|
||||
if (user != null)
|
||||
return $"{guildUser?.Nickname ?? user?.Username}";
|
||||
else
|
||||
return $"";
|
||||
case TagHandling.FullName:
|
||||
if (user != null)
|
||||
return $"@{user.Username}#{user.Discriminator}";
|
||||
else
|
||||
return $"@unknown-user";
|
||||
return $"";
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
if (user != null)
|
||||
return $"{user.Username}#{user.Discriminator}";
|
||||
else
|
||||
return $"";
|
||||
case TagHandling.Sanitize:
|
||||
if (guildUser != null && guildUser.Nickname == null)
|
||||
return MentionUser($"{SanitizeChar}{tag.Key}", false);
|
||||
@@ -166,7 +179,13 @@ namespace Discord
|
||||
if (channel != null)
|
||||
return $"#{channel.Name}";
|
||||
else
|
||||
return $"#deleted-channel";
|
||||
return $"";
|
||||
case TagHandling.NameNoPrefix:
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
if (channel != null)
|
||||
return $"{channel.Name}";
|
||||
else
|
||||
return $"";
|
||||
case TagHandling.Sanitize:
|
||||
return MentionChannel($"{SanitizeChar}{tag.Key}");
|
||||
}
|
||||
@@ -185,7 +204,13 @@ namespace Discord
|
||||
if (role != null)
|
||||
return $"@{role.Name}";
|
||||
else
|
||||
return $"@deleted-role";
|
||||
return $"";
|
||||
case TagHandling.NameNoPrefix:
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
if (role != null)
|
||||
return $"{role.Name}";
|
||||
else
|
||||
return $"";
|
||||
case TagHandling.Sanitize:
|
||||
return MentionRole($"{SanitizeChar}{tag.Key}");
|
||||
}
|
||||
@@ -200,7 +225,9 @@ namespace Discord
|
||||
{
|
||||
case TagHandling.Name:
|
||||
case TagHandling.FullName:
|
||||
return "@everyone";
|
||||
case TagHandling.NameNoPrefix:
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
return "everyone";
|
||||
case TagHandling.Sanitize:
|
||||
return $"@{SanitizeChar}everyone";
|
||||
}
|
||||
@@ -215,9 +242,11 @@ namespace Discord
|
||||
{
|
||||
case TagHandling.Name:
|
||||
case TagHandling.FullName:
|
||||
return "@everyone";
|
||||
case TagHandling.NameNoPrefix:
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
return "here";
|
||||
case TagHandling.Sanitize:
|
||||
return $"@{SanitizeChar}everyone";
|
||||
return $"@{SanitizeChar}here";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@@ -232,8 +261,11 @@ namespace Discord
|
||||
case TagHandling.Name:
|
||||
case TagHandling.FullName:
|
||||
return $":{emoji.Name}:";
|
||||
case TagHandling.NameNoPrefix:
|
||||
case TagHandling.FullNameNoPrefix:
|
||||
return $"{emoji.Name}";
|
||||
case TagHandling.Sanitize:
|
||||
return $"<@{SanitizeChar}everyone";
|
||||
return $"<{emoji.Id}{SanitizeChar}:{SanitizeChar}{emoji.Name}>";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
@@ -5,148 +5,182 @@ namespace Discord
|
||||
internal static class Preconditions
|
||||
{
|
||||
//Objects
|
||||
public static void NotNull<T>(T obj, string name) where T : class { if (obj == null) throw new ArgumentNullException(name); }
|
||||
public static void NotNull<T>(Optional<T> obj, string name) where T : class { if (obj.IsSpecified && obj.Value == null) throw new ArgumentNullException(name); }
|
||||
public static void NotNull<T>(T obj, string name, string msg = null) where T : class { if (obj == null) throw CreateNotNullException(name, msg); }
|
||||
public static void NotNull<T>(Optional<T> obj, string name, string msg = null) where T : class { if (obj.IsSpecified && obj.Value == null) throw CreateNotNullException(name, msg); }
|
||||
|
||||
private static ArgumentNullException CreateNotNullException(string name, string msg)
|
||||
{
|
||||
if (msg == null) return new ArgumentNullException(name);
|
||||
else return new ArgumentNullException(name, msg);
|
||||
}
|
||||
|
||||
//Strings
|
||||
public static void NotEmpty(string obj, string name) { if (obj.Length == 0) throw new ArgumentException("Argument cannot be empty.", name); }
|
||||
public static void NotEmpty(Optional<string> obj, string name) { if (obj.IsSpecified && obj.Value.Length == 0) throw new ArgumentException("Argument cannot be empty.", name); }
|
||||
public static void NotNullOrEmpty(string obj, string name)
|
||||
public static void NotEmpty(string obj, string name, string msg = null) { if (obj.Length == 0) throw CreateNotEmptyException(name, msg); }
|
||||
public static void NotEmpty(Optional<string> obj, string name, string msg = null) { if (obj.IsSpecified && obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); }
|
||||
public static void NotNullOrEmpty(string obj, string name, string msg = null)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(name);
|
||||
if (obj.Length == 0)
|
||||
throw new ArgumentException("Argument cannot be empty.", name);
|
||||
if (obj == null) throw CreateNotNullException(name, msg);
|
||||
if (obj.Length == 0) throw CreateNotEmptyException(name, msg);
|
||||
}
|
||||
public static void NotNullOrEmpty(Optional<string> obj, string name)
|
||||
public static void NotNullOrEmpty(Optional<string> obj, string name, string msg = null)
|
||||
{
|
||||
if (obj.IsSpecified)
|
||||
{
|
||||
if (obj.Value == null)
|
||||
throw new ArgumentNullException(name);
|
||||
if (obj.Value.Length == 0)
|
||||
throw new ArgumentException("Argument cannot be empty.", name);
|
||||
if (obj.Value == null) throw CreateNotNullException(name, msg);
|
||||
if (obj.Value.Length == 0) throw CreateNotEmptyException(name, msg);
|
||||
}
|
||||
}
|
||||
public static void NotNullOrWhitespace(string obj, string name)
|
||||
public static void NotNullOrWhitespace(string obj, string name, string msg = null)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(name);
|
||||
if (obj.Trim().Length == 0)
|
||||
throw new ArgumentException("Argument cannot be blank.", name);
|
||||
if (obj == null) throw CreateNotNullException(name, msg);
|
||||
if (obj.Trim().Length == 0) throw CreateNotEmptyException(name, msg);
|
||||
}
|
||||
public static void NotNullOrWhitespace(Optional<string> obj, string name)
|
||||
public static void NotNullOrWhitespace(Optional<string> obj, string name, string msg = null)
|
||||
{
|
||||
if (obj.IsSpecified)
|
||||
{
|
||||
if (obj.Value == null)
|
||||
throw new ArgumentNullException(name);
|
||||
if (obj.Value.Trim().Length == 0)
|
||||
throw new ArgumentException("Argument cannot be blank.", name);
|
||||
if (obj.Value == null) throw CreateNotNullException(name, msg);
|
||||
if (obj.Value.Trim().Length == 0) throw CreateNotEmptyException(name, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static ArgumentException CreateNotEmptyException(string name, string msg)
|
||||
{
|
||||
if (msg == null) return new ArgumentException(name, "Argument cannot be blank.");
|
||||
else return new ArgumentException(name, msg);
|
||||
}
|
||||
|
||||
//Numerics
|
||||
public static void NotEqual(sbyte obj, sbyte value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(byte obj, byte value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(short obj, short value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(ushort obj, ushort value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(int obj, int value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(uint obj, uint value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(long obj, long value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(ulong obj, ulong value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<sbyte> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<byte> obj, byte value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<short> obj, short value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<ushort> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<int> obj, int value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<uint> obj, uint value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<long> obj, long value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<ulong> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(sbyte? obj, sbyte value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(byte? obj, byte value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(short? obj, short value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(ushort? obj, ushort value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(int? obj, int value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(uint? obj, uint value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(long? obj, long value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(ulong? obj, ulong value, string name) { if (obj == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<sbyte?> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<byte?> obj, byte value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<short?> obj, short value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<ushort?> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<int?> obj, int value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<uint?> obj, uint value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<long?> obj, long value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(Optional<ulong?> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value == value) throw new ArgumentOutOfRangeException(name); }
|
||||
|
||||
public static void AtLeast(sbyte obj, sbyte value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(byte obj, byte value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(short obj, short value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(ushort obj, ushort value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(int obj, int value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(uint obj, uint value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(long obj, long value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(ulong obj, ulong value, string name) { if (obj < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<sbyte> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<byte> obj, byte value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<short> obj, short value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<ushort> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<int> obj, int value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<uint> obj, uint value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<long> obj, long value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtLeast(Optional<ulong> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value < value) throw new ArgumentOutOfRangeException(name); }
|
||||
|
||||
public static void GreaterThan(sbyte obj, sbyte value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(byte obj, byte value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(short obj, short value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(ushort obj, ushort value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(int obj, int value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(uint obj, uint value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(long obj, long value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(ulong obj, ulong value, string name) { if (obj <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<sbyte> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<byte> obj, byte value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<short> obj, short value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<ushort> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<int> obj, int value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<uint> obj, uint value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<long> obj, long value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void GreaterThan(Optional<ulong> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value <= value) throw new ArgumentOutOfRangeException(name); }
|
||||
|
||||
public static void AtMost(sbyte obj, sbyte value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(byte obj, byte value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(short obj, short value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(ushort obj, ushort value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(int obj, int value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(uint obj, uint value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(long obj, long value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(ulong obj, ulong value, string name) { if (obj > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<sbyte> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<byte> obj, byte value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<short> obj, short value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<ushort> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<int> obj, int value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<uint> obj, uint value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<long> obj, long value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void AtMost(Optional<ulong> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value > value) throw new ArgumentOutOfRangeException(name); }
|
||||
|
||||
public static void LessThan(sbyte obj, sbyte value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(byte obj, byte value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(short obj, short value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(ushort obj, ushort value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(int obj, int value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(uint obj, uint value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(long obj, long value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(ulong obj, ulong value, string name) { if (obj >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<sbyte> obj, sbyte value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<byte> obj, byte value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<short> obj, short value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<ushort> obj, ushort value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<int> obj, int value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<uint> obj, uint value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<long> obj, long value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void LessThan(Optional<ulong> obj, ulong value, string name) { if (obj.IsSpecified && obj.Value >= value) throw new ArgumentOutOfRangeException(name); }
|
||||
public static void NotEqual(sbyte obj, sbyte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(byte obj, byte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(short obj, short value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(ushort obj, ushort value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(int obj, int value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(uint obj, uint value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(long obj, long value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(ulong obj, ulong value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<sbyte> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<byte> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<short> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<ushort> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<int> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<uint> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<long> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<ulong> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(sbyte? obj, sbyte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(byte? obj, byte value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(short? obj, short value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(ushort? obj, ushort value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(int? obj, int value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(uint? obj, uint value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(long? obj, long value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(ulong? obj, ulong value, string name, string msg = null) { if (obj == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<sbyte?> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<byte?> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<short?> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<ushort?> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<int?> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<uint?> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<long?> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
public static void NotEqual(Optional<ulong?> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value == value) throw CreateNotEqualException(name, msg, value); }
|
||||
|
||||
private static ArgumentException CreateNotEqualException<T>(string name, string msg, T value)
|
||||
{
|
||||
if (msg == null) return new ArgumentException($"Value may not be equal to {value}", name);
|
||||
else return new ArgumentException(msg, name);
|
||||
}
|
||||
|
||||
public static void AtLeast(sbyte obj, sbyte value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(byte obj, byte value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(short obj, short value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(ushort obj, ushort value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(int obj, int value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(uint obj, uint value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(long obj, long value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(ulong obj, ulong value, string name, string msg = null) { if (obj < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<sbyte> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<byte> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<short> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<ushort> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<int> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<uint> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<long> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
public static void AtLeast(Optional<ulong> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value < value) throw CreateAtLeastException(name, msg, value); }
|
||||
|
||||
private static ArgumentException CreateAtLeastException<T>(string name, string msg, T value)
|
||||
{
|
||||
if (msg == null) return new ArgumentException($"Value must be at least {value}", name);
|
||||
else return new ArgumentException(msg, name);
|
||||
}
|
||||
|
||||
public static void GreaterThan(sbyte obj, sbyte value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(byte obj, byte value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(short obj, short value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(ushort obj, ushort value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(int obj, int value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(uint obj, uint value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(long obj, long value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(ulong obj, ulong value, string name, string msg = null) { if (obj <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<sbyte> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<byte> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<short> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<ushort> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<int> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<uint> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<long> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
public static void GreaterThan(Optional<ulong> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value <= value) throw CreateGreaterThanException(name, msg, value); }
|
||||
|
||||
private static ArgumentException CreateGreaterThanException<T>(string name, string msg, T value)
|
||||
{
|
||||
if (msg == null) return new ArgumentException($"Value must be greater than {value}", name);
|
||||
else return new ArgumentException(msg, name);
|
||||
}
|
||||
|
||||
public static void AtMost(sbyte obj, sbyte value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(byte obj, byte value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(short obj, short value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(ushort obj, ushort value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(int obj, int value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(uint obj, uint value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(long obj, long value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(ulong obj, ulong value, string name, string msg = null) { if (obj > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<sbyte> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<byte> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<short> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<ushort> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<int> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<uint> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<long> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
public static void AtMost(Optional<ulong> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value > value) throw CreateAtMostException(name, msg, value); }
|
||||
|
||||
private static ArgumentException CreateAtMostException<T>(string name, string msg, T value)
|
||||
{
|
||||
if (msg == null) return new ArgumentException($"Value must be at most {value}", name);
|
||||
else return new ArgumentException(msg, name);
|
||||
}
|
||||
|
||||
public static void LessThan(sbyte obj, sbyte value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(byte obj, byte value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(short obj, short value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(ushort obj, ushort value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(int obj, int value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(uint obj, uint value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(long obj, long value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(ulong obj, ulong value, string name, string msg = null) { if (obj >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<sbyte> obj, sbyte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<byte> obj, byte value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<short> obj, short value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<ushort> obj, ushort value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<int> obj, int value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<uint> obj, uint value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<long> obj, long value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
public static void LessThan(Optional<ulong> obj, ulong value, string name, string msg = null) { if (obj.IsSpecified && obj.Value >= value) throw CreateLessThanException(name, msg, value); }
|
||||
|
||||
private static ArgumentException CreateLessThanException<T>(string name, string msg, T value)
|
||||
{
|
||||
if (msg == null) return new ArgumentException($"Value must be less than {value}", name);
|
||||
else return new ArgumentException(msg, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0-beta2-*",
|
||||
{
|
||||
"version": "1.0.0-*",
|
||||
"description": "A .Net API wrapper and bot framework for Discord.",
|
||||
"authors": [ "RogueException" ],
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.Primitives": "4.0.1",
|
||||
"Microsoft.Win32.Primitives": "4.3.0",
|
||||
"Newtonsoft.Json": "9.0.1",
|
||||
"System.Collections.Concurrent": "4.0.12",
|
||||
"System.Collections.Immutable": "1.2.0",
|
||||
"System.Interactive.Async": "3.0.0",
|
||||
"System.Net.Http": "4.1.0",
|
||||
"System.Collections.Concurrent": "4.3.0",
|
||||
"System.Collections.Immutable": "1.3.0",
|
||||
"System.Interactive.Async": "3.1.0",
|
||||
"System.Net.Http": "4.3.0",
|
||||
"System.Net.WebSockets.Client": {
|
||||
"version": "4.0.0",
|
||||
"version": "4.3.0",
|
||||
"type": "build"
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user