From c8e8cd27b808e8f3f5d47b1cd5f64237b2c16641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Tue, 11 Nov 2025 16:37:43 +0100 Subject: [PATCH] .NET 10 (#3482) * Initial .NET 10 bump * Use KnownIPNetworks * .NET 10 library updates * First round of trimming fixes * Fix docker in .NET 10 * Resolve trimming warning * Bump packages to rc2 --- .github/workflows/ci.yml | 2 +- .github/workflows/publish.yml | 2 +- ...eamFarm.CustomPlugins.ExamplePlugin.csproj | 1 + ...iSteamFarm.CustomPlugins.PeriodicGC.csproj | 1 + ...mFarm.CustomPlugins.SignInWithSteam.csproj | 1 + ...amFarm.OfficialPlugins.ItemsMatcher.csproj | 2 +- ...OfficialPlugins.MobileAuthenticator.csproj | 1 + ...teamFarm.OfficialPlugins.Monitoring.csproj | 1 + ...rm.OfficialPlugins.SteamTokenDumper.csproj | 1 + ArchiSteamFarm/ArchiSteamFarm.csproj | 1 - ArchiSteamFarm/Core/Utilities.cs | 2 +- ArchiSteamFarm/IPC/ArchiKestrel.cs | 4 +- .../ApiAuthenticationMiddleware.cs | 6 +- .../IPC/Integration/CustomSwaggerAttribute.cs | 2 +- .../SwaggerItemsMinMaxAttribute.cs | 9 +-- .../SwaggerSecurityCriticalAttribute.cs | 23 ++++--- .../SwaggerSteamIdentifierAttribute.cs | 7 ++- .../SwaggerValidValuesAttribute.cs | 36 +++++++---- .../IPC/OpenApi/DocumentTransformer.cs | 5 +- .../IPC/OpenApi/OperationTransformer.cs | 10 +--- .../IPC/OpenApi/SchemaTransformer.cs | 60 +++++++------------ .../linux/ArchiSteamFarm-Service.sh | 6 +- .../variant-specific/docker/ArchiSteamFarm.sh | 6 +- .../generic/ArchiSteamFarm-Service.sh | 6 +- .../generic/ArchiSteamFarm.sh | 6 +- Directory.Build.props | 5 +- Directory.Packages.props | 9 ++- Dockerfile | 15 +++-- Dockerfile.Service | 15 +++-- 29 files changed, 127 insertions(+), 118 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3b3b8c74..2e723b9eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ on: [push, pull_request] env: DOTNET_CLI_TELEMETRY_OPTOUT: true DOTNET_NOLOGO: true - DOTNET_SDK_VERSION: 9.0 + DOTNET_SDK_VERSION: 10.0 permissions: {} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 830c97f56..09b76fd18 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,7 @@ env: CONFIGURATION: Release DOTNET_CLI_TELEMETRY_OPTOUT: true DOTNET_NOLOGO: true - DOTNET_SDK_VERSION: 9.0 + DOTNET_SDK_VERSION: 10.0 NODE_JS_VERSION: 'lts/*' PLUGINS_BUNDLED: ArchiSteamFarm.OfficialPlugins.ItemsMatcher ArchiSteamFarm.OfficialPlugins.MobileAuthenticator ArchiSteamFarm.OfficialPlugins.SteamTokenDumper PLUGINS_INCLUDED: ArchiSteamFarm.OfficialPlugins.Monitoring # Apart from declaring them here, there is certain amount of hardcoding needed below for uploading diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj index e52bf31f7..4f830a2e1 100644 --- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj +++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj @@ -5,6 +5,7 @@ + diff --git a/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj b/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj index 863e3b691..a20f2ad07 100644 --- a/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj +++ b/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj @@ -5,6 +5,7 @@ + diff --git a/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj b/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj index b0d04e1d9..4daeca1e8 100644 --- a/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj +++ b/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj @@ -6,6 +6,7 @@ + diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj index dab322b9b..cc63270f3 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj @@ -5,10 +5,10 @@ + - diff --git a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj index 1003d2c6f..cc63270f3 100644 --- a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj +++ b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj @@ -5,6 +5,7 @@ + diff --git a/ArchiSteamFarm.OfficialPlugins.Monitoring/ArchiSteamFarm.OfficialPlugins.Monitoring.csproj b/ArchiSteamFarm.OfficialPlugins.Monitoring/ArchiSteamFarm.OfficialPlugins.Monitoring.csproj index bea6707ef..18299a596 100644 --- a/ArchiSteamFarm.OfficialPlugins.Monitoring/ArchiSteamFarm.OfficialPlugins.Monitoring.csproj +++ b/ArchiSteamFarm.OfficialPlugins.Monitoring/ArchiSteamFarm.OfficialPlugins.Monitoring.csproj @@ -6,6 +6,7 @@ + diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj index 1003d2c6f..cc63270f3 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj @@ -5,6 +5,7 @@ + diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 908d9b9ed..11a0b40fc 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -18,7 +18,6 @@ - diff --git a/ArchiSteamFarm/Core/Utilities.cs b/ArchiSteamFarm/Core/Utilities.cs index 8420924b8..8c06b5e7b 100644 --- a/ArchiSteamFarm/Core/Utilities.cs +++ b/ArchiSteamFarm/Core/Utilities.cs @@ -313,7 +313,7 @@ public static class Utilities { // Now extract the zip file to entirely new location, this decreases chance of corruptions if user kills the process during this stage string updateDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectoryNew); - zipArchive.ExtractToDirectory(updateDirectory, true); + await zipArchive.ExtractToDirectoryAsync(updateDirectory, true).ConfigureAwait(false); // Now, critical section begins, we're going to move all files from target directory to a backup directory string backupDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectoryOld); diff --git a/ArchiSteamFarm/IPC/ArchiKestrel.cs b/ArchiSteamFarm/IPC/ArchiKestrel.cs index e379751e2..3052a9027 100644 --- a/ArchiSteamFarm/IPC/ArchiKestrel.cs +++ b/ArchiSteamFarm/IPC/ArchiKestrel.cs @@ -56,7 +56,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; using NLog.Web; using Scalar.AspNetCore; -using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork; +using IPNetwork = System.Net.IPNetwork; namespace ArchiSteamFarm.IPC; @@ -323,7 +323,7 @@ internal static class ArchiKestrel { if (knownNetworks != null) { foreach (IPNetwork knownNetwork in knownNetworks) { - options.KnownNetworks.Add(knownNetwork); + options.KnownIPNetworks.Add(knownNetwork); } } } diff --git a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs index 53ab3b7a0..f3654b32c 100644 --- a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs +++ b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs @@ -124,19 +124,19 @@ internal sealed class ApiAuthenticationMiddleware { return (HttpStatusCode.OK, true); } - if (ForwardedHeadersOptions.KnownNetworks.Count == 0) { + if (ForwardedHeadersOptions.KnownIPNetworks.Count == 0) { return (HttpStatusCode.Forbidden, true); } if (clientIP.IsIPv4MappedToIPv6) { IPAddress mappedClientIP = clientIP.MapToIPv4(); - if (ForwardedHeadersOptions.KnownNetworks.Any(network => network.Contains(mappedClientIP))) { + if (ForwardedHeadersOptions.KnownIPNetworks.Any(network => network.Contains(mappedClientIP))) { return (HttpStatusCode.OK, true); } } - return (ForwardedHeadersOptions.KnownNetworks.Any(network => network.Contains(clientIP)) ? HttpStatusCode.OK : HttpStatusCode.Forbidden, true); + return (ForwardedHeadersOptions.KnownIPNetworks.Any(network => network.Contains(clientIP)) ? HttpStatusCode.OK : HttpStatusCode.Forbidden, true); } if (!context.Request.Headers.TryGetValue(HeadersField, out StringValues passwords) && !context.Request.Query.TryGetValue("password", out passwords)) { diff --git a/ArchiSteamFarm/IPC/Integration/CustomSwaggerAttribute.cs b/ArchiSteamFarm/IPC/Integration/CustomSwaggerAttribute.cs index 2b2f29f88..3329aaddb 100644 --- a/ArchiSteamFarm/IPC/Integration/CustomSwaggerAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/CustomSwaggerAttribute.cs @@ -23,7 +23,7 @@ using System; using JetBrains.Annotations; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.Integration; diff --git a/ArchiSteamFarm/IPC/Integration/SwaggerItemsMinMaxAttribute.cs b/ArchiSteamFarm/IPC/Integration/SwaggerItemsMinMaxAttribute.cs index b45390c42..15557379e 100644 --- a/ArchiSteamFarm/IPC/Integration/SwaggerItemsMinMaxAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/SwaggerItemsMinMaxAttribute.cs @@ -22,8 +22,9 @@ // limitations under the License. using System; +using System.Globalization; using JetBrains.Annotations; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.Integration; @@ -45,16 +46,16 @@ public sealed class SwaggerItemsMinMaxAttribute : CustomSwaggerAttribute { public override void Apply(OpenApiSchema schema) { ArgumentNullException.ThrowIfNull(schema); - if (schema.Items == null) { + if (schema.Items is not OpenApiSchema items) { throw new InvalidOperationException(nameof(schema.Items)); } if (BackingMinimum.HasValue) { - schema.Items.Minimum = BackingMinimum.Value; + items.Minimum = BackingMinimum.Value.ToString(CultureInfo.InvariantCulture); } if (BackingMaximum.HasValue) { - schema.Items.Maximum = BackingMaximum.Value; + items.Maximum = BackingMaximum.Value.ToString(CultureInfo.InvariantCulture); } } } diff --git a/ArchiSteamFarm/IPC/Integration/SwaggerSecurityCriticalAttribute.cs b/ArchiSteamFarm/IPC/Integration/SwaggerSecurityCriticalAttribute.cs index df9ebbe2a..be8b369b6 100644 --- a/ArchiSteamFarm/IPC/Integration/SwaggerSecurityCriticalAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/SwaggerSecurityCriticalAttribute.cs @@ -22,10 +22,9 @@ // limitations under the License. using System; +using System.Text.Json.Nodes; using JetBrains.Annotations; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Extensions; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.Integration; @@ -36,10 +35,20 @@ public sealed class SwaggerSecurityCriticalAttribute : CustomSwaggerAttribute { public override void Apply(OpenApiSchema schema) { ArgumentNullException.ThrowIfNull(schema); - if (schema.Items is { Reference: null }) { - schema.Items.AddExtension(ExtensionName, new OpenApiBoolean(true)); - } else { - schema.AddExtension(ExtensionName, new OpenApiBoolean(true)); + JsonValue value = JsonValue.Create(true); + + if (schema.Items != null) { + if (schema.Items is OpenApiSchema items) { + items.AddExtension(ExtensionName, new JsonNodeExtension(value)); + } else if (schema.Items.Extensions != null) { + schema.Items.Extensions[ExtensionName] = new JsonNodeExtension(value); + } else { + throw new InvalidOperationException(nameof(schema.Items)); + } + + return; } + + schema.AddExtension(ExtensionName, new JsonNodeExtension(value)); } } diff --git a/ArchiSteamFarm/IPC/Integration/SwaggerSteamIdentifierAttribute.cs b/ArchiSteamFarm/IPC/Integration/SwaggerSteamIdentifierAttribute.cs index 6191e610f..fe43fc70f 100644 --- a/ArchiSteamFarm/IPC/Integration/SwaggerSteamIdentifierAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/SwaggerSteamIdentifierAttribute.cs @@ -22,8 +22,9 @@ // limitations under the License. using System; +using System.Globalization; using JetBrains.Annotations; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using SteamKit2; namespace ArchiSteamFarm.IPC.Integration; @@ -38,7 +39,7 @@ public sealed class SwaggerSteamIdentifierAttribute : CustomSwaggerAttribute { public override void Apply(OpenApiSchema schema) { ArgumentNullException.ThrowIfNull(schema); - schema.Minimum = new SteamID(MinimumAccountID, Universe, AccountType); - schema.Maximum = new SteamID(MaximumAccountID, Universe, AccountType); + schema.Minimum = new SteamID(MinimumAccountID, Universe, AccountType).ConvertToUInt64().ToString(CultureInfo.InvariantCulture); + schema.Maximum = new SteamID(MaximumAccountID, Universe, AccountType).ConvertToUInt64().ToString(CultureInfo.InvariantCulture); } } diff --git a/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs b/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs index 17344e128..d2bcc0810 100644 --- a/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs @@ -22,36 +22,50 @@ // limitations under the License. using System; -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Nodes; using JetBrains.Annotations; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Extensions; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.Integration; [PublicAPI] public sealed class SwaggerValidValuesAttribute : CustomSwaggerAttribute { + private const string ExtensionName = "x-valid-values"; + public int[]? ValidIntValues { get; init; } public string[]? ValidStringValues { get; init; } + [UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "We're not creating json values with non-primitive types")] public override void Apply(OpenApiSchema schema) { ArgumentNullException.ThrowIfNull(schema); - OpenApiArray validValues = []; + JsonArray validValues = []; if (ValidIntValues != null) { - validValues.AddRange(ValidIntValues.Select(static type => new OpenApiInteger(type))); + foreach (int value in ValidIntValues) { + validValues.Add(JsonValue.Create(value)); + } } if (ValidStringValues != null) { - validValues.AddRange(ValidStringValues.Select(static type => new OpenApiString(type))); + foreach (string value in ValidStringValues) { + validValues.Add(JsonValue.Create(value)); + } } - if (schema.Items is { Reference: null }) { - schema.Items.AddExtension("x-valid-values", validValues); - } else { - schema.AddExtension("x-valid-values", validValues); + if (schema.Items != null) { + if (schema.Items is OpenApiSchema items) { + items.AddExtension(ExtensionName, new JsonNodeExtension(validValues)); + } else if (schema.Items.Extensions != null) { + schema.Items.Extensions[ExtensionName] = new JsonNodeExtension(validValues); + } else { + throw new InvalidOperationException(nameof(schema.Items)); + } + + return; } + + schema.AddExtension(ExtensionName, new JsonNodeExtension(validValues)); } } diff --git a/ArchiSteamFarm/IPC/OpenApi/DocumentTransformer.cs b/ArchiSteamFarm/IPC/OpenApi/DocumentTransformer.cs index 23105044a..bb0916202 100644 --- a/ArchiSteamFarm/IPC/OpenApi/DocumentTransformer.cs +++ b/ArchiSteamFarm/IPC/OpenApi/DocumentTransformer.cs @@ -29,7 +29,7 @@ using ArchiSteamFarm.IPC.Integration; using ArchiSteamFarm.Storage; using JetBrains.Annotations; using Microsoft.AspNetCore.OpenApi; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.OpenApi; @@ -40,7 +40,6 @@ internal sealed class DocumentTransformer : IOpenApiDocumentTransformer { ArgumentNullException.ThrowIfNull(document); ArgumentNullException.ThrowIfNull(context); - document.Info ??= new OpenApiInfo(); document.Info.Title = $"{SharedInfo.AssemblyName} API"; document.Info.Version = SharedInfo.Version.ToString(); @@ -53,7 +52,7 @@ internal sealed class DocumentTransformer : IOpenApiDocumentTransformer { document.Info.License.Url = new Uri(SharedInfo.LicenseURL); document.Components ??= new OpenApiComponents(); - document.Components.SecuritySchemes ??= new Dictionary(1); + document.Components.SecuritySchemes ??= new Dictionary(1); document.Components.SecuritySchemes.Add( nameof(GlobalConfig.IPCPassword), new OpenApiSecurityScheme { diff --git a/ArchiSteamFarm/IPC/OpenApi/OperationTransformer.cs b/ArchiSteamFarm/IPC/OpenApi/OperationTransformer.cs index 61399b000..11f5cf66c 100644 --- a/ArchiSteamFarm/IPC/OpenApi/OperationTransformer.cs +++ b/ArchiSteamFarm/IPC/OpenApi/OperationTransformer.cs @@ -28,7 +28,7 @@ using System.Threading.Tasks; using ArchiSteamFarm.Storage; using JetBrains.Annotations; using Microsoft.AspNetCore.OpenApi; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.OpenApi; @@ -45,13 +45,7 @@ internal sealed class OperationTransformer : IOpenApiOperationTransformer { operation.Security.Add( new OpenApiSecurityRequirement { { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { - Id = nameof(GlobalConfig.IPCPassword), - Type = ReferenceType.SecurityScheme - } - }, - + new OpenApiSecuritySchemeReference(nameof(GlobalConfig.IPCPassword), context.Document), [] } } diff --git a/ArchiSteamFarm/IPC/OpenApi/SchemaTransformer.cs b/ArchiSteamFarm/IPC/OpenApi/SchemaTransformer.cs index a0eebf4b3..d353101be 100644 --- a/ArchiSteamFarm/IPC/OpenApi/SchemaTransformer.cs +++ b/ArchiSteamFarm/IPC/OpenApi/SchemaTransformer.cs @@ -23,14 +23,13 @@ using System; using System.Globalization; +using System.Text.Json.Nodes; using System.Threading; using System.Threading.Tasks; using ArchiSteamFarm.IPC.Integration; using JetBrains.Annotations; using Microsoft.AspNetCore.OpenApi; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Extensions; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; namespace ArchiSteamFarm.IPC.OpenApi; @@ -72,9 +71,9 @@ internal sealed class SchemaTransformer : IOpenApiSchemaTransformer { schema.Format = "flags"; } - OpenApiObject definition = new(); + JsonObject definition = new(); - foreach (object? enumValue in context.JsonTypeInfo.Type.GetEnumValues()) { + foreach (object? enumValue in context.JsonTypeInfo.Type.GetEnumValuesAsUnderlyingType()) { if (enumValue == null) { throw new InvalidOperationException(nameof(enumValue)); } @@ -95,41 +94,26 @@ internal sealed class SchemaTransformer : IOpenApiSchemaTransformer { continue; } - IOpenApiAny enumObject; - - if (TryCast(enumValue, out int intValue)) { - enumObject = new OpenApiInteger(intValue); - } else if (TryCast(enumValue, out long longValue)) { - enumObject = new OpenApiLong(longValue); - } else if (TryCast(enumValue, out ulong ulongValue)) { - // OpenApi spec doesn't support ulongs as of now - enumObject = new OpenApiString(ulongValue.ToString(CultureInfo.InvariantCulture)); - } else { - throw new InvalidOperationException(nameof(enumValue)); - } - - definition.Add(enumName, enumObject); + // OpenApi seems to support only int and long from underlying enum types: https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/integral-numeric-types + definition[enumName] = enumValue switch { + sbyte value => JsonValue.Create((int) value), + byte value => JsonValue.Create((int) value), + short value => JsonValue.Create((int) value), + ushort value => JsonValue.Create((int) value), + int value => JsonValue.Create(value), + uint value => JsonValue.Create((long) value), + long value => JsonValue.Create(value), + ulong value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)), + nint value when nint.Size <= 4 => JsonValue.Create((int) value), + nint value when nint.Size <= 8 => JsonValue.Create((long) value), + nint value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)), + nuint value when nuint.Size <= 4 => JsonValue.Create((long) value), + nuint value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)), + _ => throw new InvalidOperationException(nameof(enumValue)) + }; } - schema.AddExtension("x-definition", definition); - } - - private static bool TryCast(object value, out T typedValue) where T : struct { - ArgumentNullException.ThrowIfNull(value); - - try { - typedValue = (T) Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); - - return true; - } catch (InvalidCastException) { - typedValue = default(T); - - return false; - } catch (OverflowException) { - typedValue = default(T); - - return false; - } + schema.AddExtension("x-definition", new JsonNodeExtension(definition)); } } #pragma warning restore CA1812 // False positive, the class is used internally diff --git a/ArchiSteamFarm/overlay/variant-base/linux/ArchiSteamFarm-Service.sh b/ArchiSteamFarm/overlay/variant-base/linux/ArchiSteamFarm-Service.sh index 68b205a5e..dddd15a51 100755 --- a/ArchiSteamFarm/overlay/variant-base/linux/ArchiSteamFarm-Service.sh +++ b/ArchiSteamFarm/overlay/variant-base/linux/ArchiSteamFarm-Service.sh @@ -64,11 +64,11 @@ done BINARY_PREFIX="" -if [ -n "${ASF_USER-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_USER" >/dev/null 2>&1 && [ "$(id -u "$ASF_USER")" -gt 0 ]; then +if [ -n "${ASF_UID-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_UID" >/dev/null 2>&1 && [ "$(id -u "$ASF_UID")" -gt 0 ]; then # Fix permissions first to ensure ASF has read/write access to the directory specified by --path and its own - chown -hR "${ASF_USER}:${ASF_USER}" . "$SCRIPT_DIR" || true + chown -hR "${ASF_UID}:${ASF_UID}" . "$SCRIPT_DIR" || true - BINARY_PREFIX="su ${ASF_USER} -c" + BINARY_PREFIX="su $(id -nu "$ASF_UID") -c" fi CONFIG_PATH="$(pwd)/${CONFIG_PATH}" diff --git a/ArchiSteamFarm/overlay/variant-specific/docker/ArchiSteamFarm.sh b/ArchiSteamFarm/overlay/variant-specific/docker/ArchiSteamFarm.sh index b70d297f7..451b757e3 100755 --- a/ArchiSteamFarm/overlay/variant-specific/docker/ArchiSteamFarm.sh +++ b/ArchiSteamFarm/overlay/variant-specific/docker/ArchiSteamFarm.sh @@ -64,11 +64,11 @@ done BINARY_PREFIX="" -if [ -n "${ASF_USER-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_USER" >/dev/null 2>&1 && [ "$(id -u "$ASF_USER")" -gt 0 ]; then +if [ -n "${ASF_UID-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_UID" >/dev/null 2>&1 && [ "$(id -u "$ASF_UID")" -gt 0 ]; then # Fix permissions first to ensure ASF has read/write access to the directory specified by --path and its own - chown -hR "${ASF_USER}:${ASF_USER}" . "$SCRIPT_DIR" || true + chown -hR "${ASF_UID}:${ASF_UID}" . "$SCRIPT_DIR" || true - BINARY_PREFIX="su ${ASF_USER} -c" + BINARY_PREFIX="su $(id -nu "$ASF_UID") -c" fi CONFIG_PATH="$(pwd)/${CONFIG_PATH}" diff --git a/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm-Service.sh b/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm-Service.sh index df93d3701..7d5cdea33 100755 --- a/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm-Service.sh +++ b/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm-Service.sh @@ -64,11 +64,11 @@ done BINARY_PREFIX="" -if [ -n "${ASF_USER-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_USER" >/dev/null 2>&1 && [ "$(id -u "$ASF_USER")" -gt 0 ]; then +if [ -n "${ASF_UID-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_UID" >/dev/null 2>&1 && [ "$(id -u "$ASF_UID")" -gt 0 ]; then # Fix permissions first to ensure ASF has read/write access to the directory specified by --path and its own - chown -hR "${ASF_USER}:${ASF_USER}" . "$SCRIPT_DIR" || true + chown -hR "${ASF_UID}:${ASF_UID}" . "$SCRIPT_DIR" || true - BINARY_PREFIX="su ${ASF_USER} -c" + BINARY_PREFIX="su $(id -nu "$ASF_UID") -c" fi CONFIG_PATH="$(pwd)/${CONFIG_PATH}" diff --git a/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm.sh b/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm.sh index b70d297f7..451b757e3 100755 --- a/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm.sh +++ b/ArchiSteamFarm/overlay/variant-specific/generic/ArchiSteamFarm.sh @@ -64,11 +64,11 @@ done BINARY_PREFIX="" -if [ -n "${ASF_USER-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_USER" >/dev/null 2>&1 && [ "$(id -u "$ASF_USER")" -gt 0 ]; then +if [ -n "${ASF_UID-}" ] && [ "$(id -u)" -eq 0 ] && id -u "$ASF_UID" >/dev/null 2>&1 && [ "$(id -u "$ASF_UID")" -gt 0 ]; then # Fix permissions first to ensure ASF has read/write access to the directory specified by --path and its own - chown -hR "${ASF_USER}:${ASF_USER}" . "$SCRIPT_DIR" || true + chown -hR "${ASF_UID}:${ASF_UID}" . "$SCRIPT_DIR" || true - BINARY_PREFIX="su ${ASF_USER} -c" + BINARY_PREFIX="su $(id -nu "$ASF_UID") -c" fi CONFIG_PATH="$(pwd)/${CONFIG_PATH}" diff --git a/Directory.Build.props b/Directory.Build.props index f9fb07050..d747181de 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -32,11 +32,8 @@ $(PackageProjectUrl).git LatestMajor linux-arm;linux-arm64;linux-x64;osx-arm64;osx-x64;win-arm64;win-x64 - net9.0 + net10.0 true - - - false diff --git a/Directory.Packages.props b/Directory.Packages.props index c4f757d51..f05588377 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ - + @@ -18,9 +18,8 @@ - - - - + + + diff --git a/Dockerfile b/Dockerfile index eede76848..9a1080fa7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN </dev/null 2>&1; then + groupadd -r -g "$ASF_UID" "asf" + useradd -r -d "$ASF_PATH" -g "$ASF_UID" -u "$ASF_UID" "asf" + fi + + chown -hR "${ASF_UID}:${ASF_UID}" "$ASF_PATH" /asf ln -s /asf/ArchiSteamFarm.sh /usr/bin/ArchiSteamFarm EOF diff --git a/Dockerfile.Service b/Dockerfile.Service index 27c452c17..a398b1bb1 100644 --- a/Dockerfile.Service +++ b/Dockerfile.Service @@ -15,7 +15,7 @@ RUN </dev/null 2>&1; then + groupadd -r -g "$ASF_UID" "asf" + useradd -r -d "$ASF_PATH" -g "$ASF_UID" -u "$ASF_UID" "asf" + fi + + chown -hR "${ASF_UID}:${ASF_UID}" "$ASF_PATH" /asf ln -s /asf/ArchiSteamFarm-Service.sh /usr/bin/ArchiSteamFarm EOF