diff --git a/Directory.Packages.props b/Directory.Packages.props index 1423f5cd..ae3121b2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,25 +8,27 @@ - + - - - - - + + + + + + + + - + - - - - + + + - - - + + + diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index ebe41a78..55ac799f 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -124,6 +124,38 @@ Licensed under the Apache License, Version 2.0. Available at https://github.com/MassTransit/MassTransit/blob/develop/LICENSE +License notice for MassTransit.Extensions.Hosting +------------------------------------ + +Licensed under the Apache License, Version 2.0. +Available at +https://github.com/NCodeGroup/MassTransit.Extensions.Hosting/blob/master/LICENSE.txt + +License notice for Meziantou.Polyfill +------------------------------------ + +MIT License + +Copyright (c) Gérald Barré + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + License notice for Microsoft.NET.Test.Sdk ------------------------------------ @@ -187,31 +219,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [ https://www.opensource.org/licenses/bsd-license.php ] -License notice for PolySharp ------------------------------------- - -MIT License - -Copyright (c) 2022 Sergio Pedri - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - License notice for Serilog ------------------------------------ diff --git a/props/common.props b/props/common.props index 6cf6f111..ba3ee59a 100644 --- a/props/common.props +++ b/props/common.props @@ -22,7 +22,7 @@ See https://github.com/gehongyan/Kook.Net/releases MIT Logo_Small.png - net10.0;net9.0;net8.0;net462;netstandard2.0;netstandard2.1 + net10.0;net9.0;net8.0;net462;netstandard2.1;netstandard2.0 $(NoWarn);NU1803;NU1900 6 true @@ -35,25 +35,31 @@ $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix) + + $(DefineConstants);SUPPORTS_ASYNC_DISPOSABLE + true - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + - + - - - - + + + + diff --git a/src/Kook.Net.CardMarkup/CardMarkupSerializer.cs b/src/Kook.Net.CardMarkup/CardMarkupSerializer.cs index faff03d1..e9d22ce5 100644 --- a/src/Kook.Net.CardMarkup/CardMarkupSerializer.cs +++ b/src/Kook.Net.CardMarkup/CardMarkupSerializer.cs @@ -22,11 +22,10 @@ public static class CardMarkupSerializer /// 一个表示异步解析操作的任务。任务的结果包含一个可用于枚举 成员的 public static async Task> DeserializeAsync(FileInfo file, CancellationToken token = default) { -#if NETSTANDARD2_0 || NET462 - using FileStream fs = file.OpenRead(); -#else - await using FileStream fs = file.OpenRead(); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif + using FileStream fs = file.OpenRead(); return await DeserializeAsync(fs, token); } diff --git a/src/Kook.Net.Commands/Map/CommandMapNode.cs b/src/Kook.Net.Commands/Map/CommandMapNode.cs index 3272a103..f658be6a 100644 --- a/src/Kook.Net.Commands/Map/CommandMapNode.cs +++ b/src/Kook.Net.Commands/Map/CommandMapNode.cs @@ -9,11 +9,7 @@ internal class CommandMapNode private readonly ConcurrentDictionary _nodes; private readonly string _name; -#if NET9_0_OR_GREATER private readonly Lock _lockObj = new(); -#else - private readonly object _lockObj = new(); -#endif private ImmutableArray _commands; // ReSharper disable InconsistentlySynchronizedField diff --git a/src/Kook.Net.Commands/PrimitiveParsers.cs b/src/Kook.Net.Commands/PrimitiveParsers.cs index c5e7f6c3..ba7a91a0 100644 --- a/src/Kook.Net.Commands/PrimitiveParsers.cs +++ b/src/Kook.Net.Commands/PrimitiveParsers.cs @@ -28,7 +28,7 @@ private static IReadOnlyDictionary CreateParsers() parserBuilder[typeof(DateTime)] = (TryParseDelegate)DateTime.TryParse; parserBuilder[typeof(DateTimeOffset)] = (TryParseDelegate)DateTimeOffset.TryParse; parserBuilder[typeof(Guid)] = (TryParseDelegate)Guid.TryParse; -#if NET6_0_OR_GREATER +#if NET parserBuilder[typeof(DateOnly)] = (TryParseDelegate)DateOnly.TryParse; parserBuilder[typeof(TimeOnly)] = (TryParseDelegate)TimeOnly.TryParse; #endif diff --git a/src/Kook.Net.Core/Extensions/CollectionExtensions.cs b/src/Kook.Net.Core/Extensions/CollectionExtensions.cs index 636c41a6..7e5f3d54 100644 --- a/src/Kook.Net.Core/Extensions/CollectionExtensions.cs +++ b/src/Kook.Net.Core/Extensions/CollectionExtensions.cs @@ -5,61 +5,118 @@ namespace Kook; internal static class CollectionExtensions { - //public static IReadOnlyCollection ToReadOnlyCollection(this IReadOnlyCollection source) - // => new CollectionWrapper(source, () => source.Count); + // extension(IReadOnlyCollection source) + // { + // public IReadOnlyCollection ToReadOnlyCollection() + // => new CollectionWrapper(source, () => source.Count); + // } - public static IReadOnlyCollection ToReadOnlyCollection(this ICollection source) => - new CollectionWrapper(source, () => source.Count); + extension(ICollection source) + { + public IReadOnlyCollection ToReadOnlyCollection() => + new CollectionWrapper(source, () => source.Count); + } + + // extension(IReadOnlyDictionary source) + // { + // public IReadOnlyCollection ToReadOnlyCollection() + // => new CollectionWrapper(source.Select(x => x.Value), () => source.Count); + // } + + extension(IDictionary source) + { + public IReadOnlyCollection ToReadOnlyCollection() => + new CollectionWrapper(source.Values, () => source.Count); + } + + extension(IEnumerable query) + { + public IReadOnlyCollection ToReadOnlyCollection(IReadOnlyCollection source) => + new CollectionWrapper(query, () => source.Count); + + public IReadOnlyCollection ToReadOnlyCollection(Func countFunc) => + new CollectionWrapper(query, countFunc); - //public static IReadOnlyCollection ToReadOnlyCollection(this IReadOnlyDictionary source) - // => new CollectionWrapper(source.Select(x => x.Value), () => source.Count); +#if NETSTANDARD || NETFRAMEWORK + public IEnumerable Chunk(int size) + { + if (query is null) + throw new ArgumentNullException(nameof(query)); - public static IReadOnlyCollection ToReadOnlyCollection(this IDictionary source) => - new CollectionWrapper(source.Values, () => source.Count); + if (size <= 0) + throw new ArgumentOutOfRangeException(nameof(size)); - public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable query, - IReadOnlyCollection source) => - new CollectionWrapper(query, () => source.Count); + return ChunkIterator(query, size); - public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable query, Func countFunc) => - new CollectionWrapper(query, countFunc); + static IEnumerable ChunkIterator(IEnumerable source, int size) + { + using IEnumerator e = source.GetEnumerator(); -#if !NET6_0_OR_GREATER - public static TSource? MinBy( - this IEnumerable source, - Func keySelector) => - source.OrderBy(keySelector).FirstOrDefault(); + // Before allocating anything, make sure there's at least one element. + if (e.MoveNext()) + { + // Now that we know we have at least one item, allocate an initial storage array. This is not + // the array we'll yield. It starts out small in order to avoid significantly overallocating + // when the source has many fewer elements than the chunk size. + int arraySize = Math.Min(size, 4); + int i; + do + { + TValue[]? array = new TValue[arraySize]; - public static TSource? MaxBy( - this IEnumerable source, - Func keySelector) => - source.OrderByDescending(keySelector).FirstOrDefault(); + // Store the first item. + array[0] = e.Current; + i = 1; - public static IEnumerable> Chunk(this IEnumerable source, int chunkSize) => - source - .Select((x, i) => new { Index = i, Value = x }) - .GroupBy(x => x.Index / chunkSize) - .Select(x => x.Select(v => v.Value)); + if (size != array.Length) + { + // This is the first chunk. As we fill the array, grow it as needed. + for (; i < size && e.MoveNext(); i++) + { + if (i >= array.Length) + { + arraySize = (int)Math.Min((uint)size, 2 * (uint)array.Length); + Array.Resize(ref array, arraySize); + } + + array[i] = e.Current; + } + } + else + { + // For all but the first chunk, the array will already be correctly sized. + // We can just store into it until either it's full or MoveNext returns false. + TValue[] local = array; // avoid bounds checks by using cached local (`array` is lifted to iterator object as a field) + for (; (uint)i < (uint)local.Length && e.MoveNext(); i++) + { + local[i] = e.Current; + } + } + + if (i != array.Length) + { + Array.Resize(ref array, i); + } + + yield return array; + } + while (i >= size && e.MoveNext()); + } + } + } #endif + } } [DebuggerDisplay("{DebuggerDisplay,nq}")] -internal readonly struct CollectionWrapper : IReadOnlyCollection +internal readonly struct CollectionWrapper + (IEnumerable query, Func countFunc) : IReadOnlyCollection { - private readonly IEnumerable _query; - private readonly Func _countFunc; - //It's okay that this count is affected by race conditions - we're wrapping a concurrent collection and that's to be expected - public int Count => _countFunc(); - - public CollectionWrapper(IEnumerable query, Func countFunc) - { - _query = query; - _countFunc = countFunc; - } + public int Count => countFunc(); private string DebuggerDisplay => $"Count = {Count}"; - public IEnumerator GetEnumerator() => _query.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => _query.GetEnumerator(); + public IEnumerator GetEnumerator() => query.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => query.GetEnumerator(); } diff --git a/src/Kook.Net.Core/GlobalUsings.cs b/src/Kook.Net.Core/GlobalUsings.cs new file mode 100644 index 00000000..ed5439ff --- /dev/null +++ b/src/Kook.Net.Core/GlobalUsings.cs @@ -0,0 +1,3 @@ +#if NETFRAMEWORK +global using System.Net.Http; +#endif diff --git a/src/Kook.Net.Core/Kook.Net.Core.csproj b/src/Kook.Net.Core/Kook.Net.Core.csproj index 19237bd4..53940773 100644 --- a/src/Kook.Net.Core/Kook.Net.Core.csproj +++ b/src/Kook.Net.Core/Kook.Net.Core.csproj @@ -7,10 +7,26 @@ The core definition library for Kook.Net. + + + + + + + + + + + + + - + + + + diff --git a/src/Kook.Net.Core/Net/BucketId.cs b/src/Kook.Net.Core/Net/BucketId.cs index 9b0b46e9..e4b0ebf0 100644 --- a/src/Kook.Net.Core/Net/BucketId.cs +++ b/src/Kook.Net.Core/Net/BucketId.cs @@ -1,7 +1,4 @@ using System.Diagnostics.CodeAnalysis; -#if NET462 -using System.Net.Http; -#endif namespace Kook.Net; diff --git a/src/Kook.Net.Core/Net/Rest/IRestClient.cs b/src/Kook.Net.Core/Net/Rest/IRestClient.cs index ea9914f8..8d5c9017 100644 --- a/src/Kook.Net.Core/Net/Rest/IRestClient.cs +++ b/src/Kook.Net.Core/Net/Rest/IRestClient.cs @@ -1,7 +1,3 @@ -#if NET462 -using System.Net.Http; -#endif - namespace Kook.Net.Rest; /// diff --git a/src/Kook.Net.Core/Utils/AsyncEvent.cs b/src/Kook.Net.Core/Utils/AsyncEvent.cs index 884bbd25..2a285172 100644 --- a/src/Kook.Net.Core/Utils/AsyncEvent.cs +++ b/src/Kook.Net.Core/Utils/AsyncEvent.cs @@ -5,11 +5,7 @@ namespace Kook; internal class AsyncEvent where T : class { -#if NET9_0_OR_GREATER private readonly Lock _subLock = new(); -#else - private readonly object _subLock = new(); -#endif internal ImmutableArray _subscriptions = []; // ReSharper disable once InconsistentlySynchronizedField diff --git a/src/Kook.Net.Core/Utils/PolyfillUtils.cs b/src/Kook.Net.Core/Utils/PolyfillUtils.cs new file mode 100644 index 00000000..a66bda1c --- /dev/null +++ b/src/Kook.Net.Core/Utils/PolyfillUtils.cs @@ -0,0 +1,11 @@ +namespace Kook; + +internal static class PolyfillUtils +{ +#if NETSTANDARD2_0 || NETFRAMEWORK + extension(DateTimeOffset) + { + public static DateTimeOffset UnixEpoch => new(621355968000000000L, TimeSpan.Zero); + } +#endif +} diff --git a/src/Kook.Net.DependencyInjection.Microsoft/Kook.Net.DependencyInjection.Microsoft.csproj b/src/Kook.Net.DependencyInjection.Microsoft/Kook.Net.DependencyInjection.Microsoft.csproj index be402cfc..5c0501f2 100644 --- a/src/Kook.Net.DependencyInjection.Microsoft/Kook.Net.DependencyInjection.Microsoft.csproj +++ b/src/Kook.Net.DependencyInjection.Microsoft/Kook.Net.DependencyInjection.Microsoft.csproj @@ -11,11 +11,11 @@ - + - + diff --git a/src/Kook.Net.Experimental/GlobalUsings.cs b/src/Kook.Net.Experimental/GlobalUsings.cs new file mode 100644 index 00000000..ed5439ff --- /dev/null +++ b/src/Kook.Net.Experimental/GlobalUsings.cs @@ -0,0 +1,3 @@ +#if NETFRAMEWORK +global using System.Net.Http; +#endif diff --git a/src/Kook.Net.Experimental/Rest/KookRestApiClientExperimentalExtensions.cs b/src/Kook.Net.Experimental/Rest/KookRestApiClientExperimentalExtensions.cs index e5af4888..946231e2 100644 --- a/src/Kook.Net.Experimental/Rest/KookRestApiClientExperimentalExtensions.cs +++ b/src/Kook.Net.Experimental/Rest/KookRestApiClientExperimentalExtensions.cs @@ -1,7 +1,3 @@ -#if NET462 -using System.Net.Http; -#endif - using Kook.API; using Kook.API.Rest; using Kook.Net.Queue; diff --git a/src/Kook.Net.Hosting/Kook.Net.Hosting.csproj b/src/Kook.Net.Hosting/Kook.Net.Hosting.csproj index 452e5bf9..753d3557 100644 --- a/src/Kook.Net.Hosting/Kook.Net.Hosting.csproj +++ b/src/Kook.Net.Hosting/Kook.Net.Hosting.csproj @@ -11,11 +11,11 @@ - + - + diff --git a/src/Kook.Net.MessageQueue.InMemory/BufferedInMemoryMessageQueue.cs b/src/Kook.Net.MessageQueue.InMemory/BufferedInMemoryMessageQueue.cs index 7e5e241a..81cc3da0 100644 --- a/src/Kook.Net.MessageQueue.InMemory/BufferedInMemoryMessageQueue.cs +++ b/src/Kook.Net.MessageQueue.InMemory/BufferedInMemoryMessageQueue.cs @@ -10,11 +10,7 @@ namespace Kook.Net.Queue.InMemory; internal sealed class BufferedInMemoryMessageQueue : BaseMessageQueue { private readonly InMemoryMessageQueueOptions _options; -#if NET9_0_OR_GREATER private readonly Lock _lock = new(); -#else - private readonly object _lock = new(); -#endif private readonly SortedDictionary _buffer = new(); private readonly Channel _outputChannel; private readonly int _maxSeq; diff --git a/src/Kook.Net.Pipe/GlobalUsings.cs b/src/Kook.Net.Pipe/GlobalUsings.cs new file mode 100644 index 00000000..ed5439ff --- /dev/null +++ b/src/Kook.Net.Pipe/GlobalUsings.cs @@ -0,0 +1,3 @@ +#if NETFRAMEWORK +global using System.Net.Http; +#endif diff --git a/src/Kook.Net.Pipe/KookPipeClient.cs b/src/Kook.Net.Pipe/KookPipeClient.cs index bb89a54c..34009f52 100644 --- a/src/Kook.Net.Pipe/KookPipeClient.cs +++ b/src/Kook.Net.Pipe/KookPipeClient.cs @@ -7,10 +7,6 @@ using Kook.Logging; using Kook.Rest; -#if NET462 -using System.Net.Http; -#endif - namespace Kook.Pipe; /// @@ -232,7 +228,7 @@ private static NameValueCollection ParseQueryString(Uri url) if (string.IsNullOrWhiteSpace(url.Query)) throw new ArgumentNullException(nameof(url), "The given pipe URL does not contain a query string."); -#if NET462 +#if NETFRAMEWORK NameValueCollection collection = []; foreach (string queryItem in url.Query.TrimStart('?').Split('&')) { diff --git a/src/Kook.Net.Rest/BaseKookClient.cs b/src/Kook.Net.Rest/BaseKookClient.cs index 44bcad7a..b8d3d266 100644 --- a/src/Kook.Net.Rest/BaseKookClient.cs +++ b/src/Kook.Net.Rest/BaseKookClient.cs @@ -1,7 +1,3 @@ -#if NET462 -using System.Net.Http; -#endif - using System.Collections.Immutable; using Kook.Logging; @@ -172,7 +168,7 @@ internal virtual async Task LoginInternalAsync(TokenType tokenType, string token } catch (ArgumentException ex) { - // log these ArgumentExceptions and allow for the client to attempt to log in anyways + // log these ArgumentExceptions and allow for the client to attempt to log in any ways await LogManager.WarningAsync("Kook", "A supplied token was invalid.", ex).ConfigureAwait(false); } } diff --git a/src/Kook.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Kook.Net.Rest/Entities/Messages/MessageHelper.cs index dac90c83..4c3f649f 100644 --- a/src/Kook.Net.Rest/Entities/Messages/MessageHelper.cs +++ b/src/Kook.Net.Rest/Entities/Messages/MessageHelper.cs @@ -491,10 +491,10 @@ public static ImmutableArray ParseTags(string text, IMessageChannel? chann _ => throw new ArgumentOutOfRangeException(nameof(tagMode), tagMode, null) }; -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - foreach (Match match in matchCollection.Where(m => m.Success)) -#else +#if NETSTANDARD2_0 || NETFRAMEWORK foreach (Match match in matchCollection.Cast().Where(m => m.Success)) +#else + foreach (Match match in matchCollection.Where(m => m.Success)) #endif { index = match.Index; diff --git a/src/Kook.Net.Rest/GlobalUsings.cs b/src/Kook.Net.Rest/GlobalUsings.cs new file mode 100644 index 00000000..ed5439ff --- /dev/null +++ b/src/Kook.Net.Rest/GlobalUsings.cs @@ -0,0 +1,3 @@ +#if NETFRAMEWORK +global using System.Net.Http; +#endif diff --git a/src/Kook.Net.Rest/Kook.Net.Rest.csproj b/src/Kook.Net.Rest/Kook.Net.Rest.csproj index a29571bf..64f8c6b3 100644 --- a/src/Kook.Net.Rest/Kook.Net.Rest.csproj +++ b/src/Kook.Net.Rest/Kook.Net.Rest.csproj @@ -1,5 +1,5 @@ - + Kook.Rest true @@ -7,15 +7,6 @@ The REST API implementation for Kook.Net. - + - - - - - - - - - - \ No newline at end of file + diff --git a/src/Kook.Net.Rest/KookRestApiClient.cs b/src/Kook.Net.Rest/KookRestApiClient.cs index 164cab6d..1cc1f716 100644 --- a/src/Kook.Net.Rest/KookRestApiClient.cs +++ b/src/Kook.Net.Rest/KookRestApiClient.cs @@ -1,7 +1,3 @@ -#if NET462 -using System.Net.Http; -#endif - using System.Collections.Concurrent; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -1965,7 +1961,7 @@ protected void CheckState() [return: NotNullIfNotNull(nameof(content))] protected static string? UrlEncode(string? content) { -#if NET462 +#if NETFRAMEWORK return System.Net.WebUtility.UrlEncode(content); #else return System.Web.HttpUtility.UrlEncode(content); diff --git a/src/Kook.Net.Rest/KookRestClient.cs b/src/Kook.Net.Rest/KookRestClient.cs index bc13bb00..d5f9772f 100644 --- a/src/Kook.Net.Rest/KookRestClient.cs +++ b/src/Kook.Net.Rest/KookRestClient.cs @@ -316,12 +316,12 @@ public Task RemoveDirectMessageReactionAsync(Guid messageId, ulong userId, IEmot /// 一个表示异步创建操作的任务。任务的结果是上传文件后的资源地址 URL。 public async Task CreateAssetAsync(string path, string? filename = null, RequestOptions? options = null) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - await using FileStream fileStream = File.OpenRead(path); -#else - using FileStream fileStream = File.OpenRead(path); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif - return await ClientHelper.CreateAssetAsync(this, fileStream, filename ?? Path.GetFileName(path), options) + using FileStream fileStream = File.OpenRead(path); + return await ClientHelper + .CreateAssetAsync(this, fileStream, filename ?? Path.GetFileName(path), options) .ConfigureAwait(false); } diff --git a/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeMillisecondsConverter.cs b/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeMillisecondsConverter.cs index 72ef53fc..41835dd4 100644 --- a/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeMillisecondsConverter.cs +++ b/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeMillisecondsConverter.cs @@ -10,11 +10,7 @@ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConver public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER if (value == DateTimeOffset.MinValue || value == DateTimeOffset.UnixEpoch) -#else - if (value == DateTimeOffset.MinValue || value == new DateTimeOffset(621355968000000000L, TimeSpan.Zero)) -#endif writer.WriteNullValue(); else writer.WriteNumberValue(value.ToUnixTimeMilliseconds()); diff --git a/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeSecondsConverter.cs b/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeSecondsConverter.cs index 13798982..88cfa4e5 100644 --- a/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeSecondsConverter.cs +++ b/src/Kook.Net.Rest/Net/Converters/DateTimeOffsetUnixTimeSecondsConverter.cs @@ -10,11 +10,7 @@ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConver public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER if (value == DateTimeOffset.MinValue || value == DateTimeOffset.UnixEpoch) -#else - if (value == DateTimeOffset.MinValue || value == new DateTimeOffset(621355968000000000L, TimeSpan.Zero)) -#endif writer.WriteNullValue(); else writer.WriteNumberValue(value.ToUnixTimeSeconds()); diff --git a/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeMillisecondsConverter.cs b/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeMillisecondsConverter.cs index b9f68032..2c4ca27c 100644 --- a/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeMillisecondsConverter.cs +++ b/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeMillisecondsConverter.cs @@ -21,11 +21,7 @@ internal class NullableDateTimeOffsetUnixTimeMillisecondsConverter : JsonConvert public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER if (!value.HasValue || value == DateTimeOffset.MinValue || value == DateTimeOffset.UnixEpoch) -#else - if (!value.HasValue || value == DateTimeOffset.MinValue || value == new DateTimeOffset(621355968000000000L, TimeSpan.Zero)) -#endif writer.WriteNullValue(); else writer.WriteNumberValue(value.Value.ToUnixTimeMilliseconds()); diff --git a/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeSecondsConverter.cs b/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeSecondsConverter.cs index 867a05cf..a84d47c3 100644 --- a/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeSecondsConverter.cs +++ b/src/Kook.Net.Rest/Net/Converters/NullableDateTimeOffsetUnixTimeSecondsConverter.cs @@ -21,11 +21,7 @@ internal class NullableDateTimeOffsetUnixTimeSecondsConverter : JsonConverter diff --git a/src/Kook.Net.WebSocket/Kook.Net.WebSocket.csproj b/src/Kook.Net.WebSocket/Kook.Net.WebSocket.csproj index f2d4e984..291f1d55 100644 --- a/src/Kook.Net.WebSocket/Kook.Net.WebSocket.csproj +++ b/src/Kook.Net.WebSocket/Kook.Net.WebSocket.csproj @@ -11,7 +11,4 @@ - - - - \ No newline at end of file + diff --git a/src/Kook.Net.WebSocket/KookSocketApiClient.cs b/src/Kook.Net.WebSocket/KookSocketApiClient.cs index 547d9e01..95b40d3c 100644 --- a/src/Kook.Net.WebSocket/KookSocketApiClient.cs +++ b/src/Kook.Net.WebSocket/KookSocketApiClient.cs @@ -80,19 +80,17 @@ public KookSocketApiClient(RestClientProvider restClientProvider, private async Task OnBinaryMessage(byte[] data, int index, int count) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - await using MemoryStream decompressed = new(); -#else - using MemoryStream decompressed = new(); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif + using MemoryStream decompressed = new(); using MemoryStream compressed = data[0] == 0x78 ? new MemoryStream(data, index + 2, count - 2) : new MemoryStream(data, index, count); -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - await using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); -#else - using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif + using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); await decompressor.CopyToAsync(decompressed); decompressed.Position = 0; diff --git a/src/Kook.Net.Webhook.HttpListener/Net/HttpListener/HttpListenerWebhookClient.cs b/src/Kook.Net.Webhook.HttpListener/Net/HttpListener/HttpListenerWebhookClient.cs index 0c49a3ce..4a8a225e 100644 --- a/src/Kook.Net.Webhook.HttpListener/Net/HttpListener/HttpListenerWebhookClient.cs +++ b/src/Kook.Net.Webhook.HttpListener/Net/HttpListener/HttpListenerWebhookClient.cs @@ -197,20 +197,16 @@ private async Task HandleRequestAsync(HttpListenerContext context) if (context.Request.QueryString["compress"]?.Split(',').Any(x => x.StartsWith("0")) is true) { using StreamReader streamReader = new(context.Request.InputStream); -#if NET7_0_OR_GREATER string requestBody = await streamReader.ReadToEndAsync(_cancellationToken); -#else - string requestBody = await streamReader.ReadToEndAsync(); -#endif messageResponse = await HandleTextMessageAsync(requestBody); } else { using MemoryStream stream = new(); -#if NET7_0_OR_GREATER - await context.Request.InputStream.CopyToAsync(stream, _cancellationToken); -#else +#if NETSTANDARD2_0 || NETFRAMEWORK await context.Request.InputStream.CopyToAsync(stream); +#else + await context.Request.InputStream.CopyToAsync(stream, _cancellationToken); #endif byte[] bytes = stream.ToArray(); messageResponse = await HandleBinaryMessageAsync(bytes, 0, bytes.Length); @@ -218,21 +214,16 @@ private async Task HandleRequestAsync(HttpListenerContext context) if (messageResponse is not null) { -#if NETSTANDARD2_0 || NET462 - using StreamWriter writer = new(context.Response.OutputStream); -#else - await using StreamWriter writer = new(context.Response.OutputStream); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif + using StreamWriter writer = new(context.Response.OutputStream); await writer.WriteAsync(messageResponse); } else { context.Response.StatusCode = (int)HttpStatusCode.NoContent; -#if NETSTANDARD2_0 || NET462 - await context.Response.OutputStream.WriteAsync([], 0, 0, _cancellationToken); -#else await context.Response.OutputStream.WriteAsync(ReadOnlyMemory.Empty, _cancellationToken); -#endif } } catch diff --git a/src/Kook.Net.Webhook/KookWebhookApiClient.cs b/src/Kook.Net.Webhook/KookWebhookApiClient.cs index ea99aa53..2517d6c0 100644 --- a/src/Kook.Net.Webhook/KookWebhookApiClient.cs +++ b/src/Kook.Net.Webhook/KookWebhookApiClient.cs @@ -58,27 +58,24 @@ public KookWebhookApiClient(RestClientProvider restClientProvider, private async Task OnBinaryMessage(byte[] data, int index, int count) { -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - await using MemoryStream decompressed = new(); -#else +#if SUPPORTS_ASYNC_DISPOSABLE + await +#endif using MemoryStream decompressed = new(); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif using MemoryStream compressed = data[0] == 0x78 ? new MemoryStream(data, index + 2, count - 2) : new MemoryStream(data, index, count); -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER - await using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); -#else - using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); +#if SUPPORTS_ASYNC_DISPOSABLE + await #endif + using DeflateStream decompressor = new(compressed, CompressionMode.Decompress); await decompressor.CopyToAsync(decompressed); decompressed.Position = 0; -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER GatewayEncryptedFrame? gatewayEncryptedFrame = await JsonSerializer.DeserializeAsync(decompressed, _serializerOptions); -#else - GatewayEncryptedFrame? gatewayEncryptedFrame = JsonSerializer.Deserialize(decompressed, _serializerOptions); -#endif if (gatewayEncryptedFrame is null) return null; string decryptedFrame = Decrypt(gatewayEncryptedFrame.Encrypted, _encryptKey); diff --git a/test/Kook.Net.Tests.Unit/ModuleBuilderTests.cs b/test/Kook.Net.Tests.Unit/ModuleBuilderTests.cs index 9dfe1227..6a054042 100644 --- a/test/Kook.Net.Tests.Unit/ModuleBuilderTests.cs +++ b/test/Kook.Net.Tests.Unit/ModuleBuilderTests.cs @@ -581,11 +581,7 @@ public void CountdownModuleBuilder_InvalidTimes() yield return (CountdownMode.Day, DateTimeOffset.Now.AddDays(-1), null); yield return (CountdownMode.Hour, DateTimeOffset.Now.AddDays(-1), null); // StartTime must be equal or later than Unix Epoch -#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER yield return (CountdownMode.Second, DateTimeOffset.Now.AddMinutes(1), DateTimeOffset.UnixEpoch.AddTicks(-1)); -#else - yield return (CountdownMode.Second, DateTimeOffset.Now.AddMinutes(1), new DateTimeOffset(621355968000000000L, TimeSpan.Zero).AddTicks(-1)); -#endif // EndTime must be later than StartTime yield return (CountdownMode.Second, DateTimeOffset.Now.AddMinutes(1), DateTimeOffset.Now.AddMinutes(1)); yield return (CountdownMode.Second, DateTimeOffset.Now.AddMinutes(1), DateTimeOffset.Now.AddMinutes(2));