diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index f315fe6..c1a2b54 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -8,6 +8,10 @@ on:
pull_request:
branches: [ "master" ]
+permissions:
+ contents: read
+ actions: write
+
jobs:
build:
@@ -18,7 +22,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 9.0.x
+ dotnet-version: 10.0.x
- name: download JSON submodule
run: git submodule update --init ./src/Helldivers-2-Models/json
- name: Restore dependencies
@@ -36,3 +40,22 @@ jobs:
retention-days: 5
name: openapi-schemas
path: docs/openapi/
+
+ docker-build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Build Docker image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ./src/Helldivers-2-API/Dockerfile
+ push: false
+ tags: helldivers-api:test
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index e66e0b6..14ad50e 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -31,7 +31,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 9.0.x
+ dotnet-version: 10.0.x
- name: Generate OpenAPI JSON files
run: dotnet build -c Debug
- name: Copy README
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index 1a5af52..f56d754 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -23,7 +23,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '9.0.x'
+ dotnet-version: '10.0.x'
- name: Download JSON submodule
run: git submodule update --init ./src/Helldivers-2-Models/json
diff --git a/Directory.Build.props b/Directory.Build.props
index bf255bb..bc2f4d4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -2,7 +2,7 @@
enable
enable
- net9.0
+ net10.0
true
diff --git a/src/Helldivers-2-API/Dockerfile b/src/Helldivers-2-API/Dockerfile
index 2cad5bd..e53d752 100644
--- a/src/Helldivers-2-API/Dockerfile
+++ b/src/Helldivers-2-API/Dockerfile
@@ -1,9 +1,9 @@
-FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine-extra AS base
+FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine-extra AS base
USER $APP_UID
WORKDIR /app
-FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
-RUN apk add --upgrade --no-cache build-base clang zlib-dev
+FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine-aot AS build
+RUN apk add --no-cache build-base clang lld llvm zlib-dev libstdc++
ARG BUILD_CONFIGURATION=Release
ARG BUILD_RUNTIME=linux-musl-x64
ARG OPENAPI=false
@@ -35,7 +35,9 @@ RUN dotnet build "Helldivers-2-API.csproj" --no-restore -r $BUILD_RUNTIME -c $BU
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
-RUN dotnet publish "Helldivers-2-API.csproj" /p:Version="$VERSION" --no-restore --self-contained -r $BUILD_RUNTIME -c $BUILD_CONFIGURATION -o /app/publish
+ARG BUILD_RUNTIME=linux-musl-x64
+ARG VERSION=0.0.0
+RUN dotnet publish "Helldivers-2-API.csproj" /p:Version="$VERSION" --self-contained -r $BUILD_RUNTIME -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final
WORKDIR /app
diff --git a/src/Helldivers-2-API/Helldivers-2-API.csproj b/src/Helldivers-2-API/Helldivers-2-API.csproj
index 57bcee3..e691df0 100644
--- a/src/Helldivers-2-API/Helldivers-2-API.csproj
+++ b/src/Helldivers-2-API/Helldivers-2-API.csproj
@@ -4,8 +4,8 @@
true
Helldivers.API
Linux
- true
true
+ true
@@ -23,8 +23,9 @@
-
-
+
+
+
@@ -36,12 +37,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/Helldivers-2-API/OpenApi/TypeMappers/EnumStringTypeMapper.cs b/src/Helldivers-2-API/OpenApi/TypeMappers/EnumStringTypeMapper.cs
index ad77a62..3869268 100644
--- a/src/Helldivers-2-API/OpenApi/TypeMappers/EnumStringTypeMapper.cs
+++ b/src/Helldivers-2-API/OpenApi/TypeMappers/EnumStringTypeMapper.cs
@@ -1,4 +1,5 @@
-using NJsonSchema;
+#if DEBUG
+using NJsonSchema;
using NJsonSchema.Generation.TypeMappers;
using System.Collections.ObjectModel;
@@ -34,3 +35,4 @@ public void GenerateSchema(JsonSchema schema, TypeMapperContext context)
schema.ExtensionData ??= new Dictionary()!;
}
}
+#endif
diff --git a/src/Helldivers-2-API/Program.cs b/src/Helldivers-2-API/Program.cs
index 33dd3ac..c87e91d 100644
--- a/src/Helldivers-2-API/Program.cs
+++ b/src/Helldivers-2-API/Program.cs
@@ -91,8 +91,8 @@
options.ForwardLimit = 999;
options.OriginalForHeaderName = "Fly-Client-IP";
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor;
- options.KnownNetworks.Add(new IPNetwork(IPAddress.Any, 0));
- options.KnownNetworks.Add(new IPNetwork(IPAddress.IPv6Any, 0));
+ options.KnownIPNetworks.Add(new System.Net.IPNetwork(IPAddress.Any, 0));
+ options.KnownIPNetworks.Add(new System.Net.IPNetwork(IPAddress.IPv6Any, 0));
});
// This configuration is bound here so that source generators kick in.
@@ -219,6 +219,9 @@
// Ensure web applications can access the API by setting CORS headers.
app.UseCors();
+// Add various security-related headers.
+app.UseSecurityHeaders();
+
// Make sure ASP.NET Core uses the correct addresses internally rather than Fly's proxy
app.UseForwardedHeaders();
diff --git a/src/Helldivers-2-CI/Helldivers-2-CI.csproj b/src/Helldivers-2-CI/Helldivers-2-CI.csproj
index 76bce0f..15a4fea 100644
--- a/src/Helldivers-2-CI/Helldivers-2-CI.csproj
+++ b/src/Helldivers-2-CI/Helldivers-2-CI.csproj
@@ -2,13 +2,13 @@
Exe
- net9.0
+ net10.0
Helldivers_2_CI
false
-
+
diff --git a/src/Helldivers-2-Core/Helldivers-2-Core.csproj b/src/Helldivers-2-Core/Helldivers-2-Core.csproj
index 0d66e02..ece9726 100644
--- a/src/Helldivers-2-Core/Helldivers-2-Core.csproj
+++ b/src/Helldivers-2-Core/Helldivers-2-Core.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/src/Helldivers-2-SourceGen/Helldivers-2-SourceGen.csproj b/src/Helldivers-2-SourceGen/Helldivers-2-SourceGen.csproj
index 55e74cf..98e54f2 100644
--- a/src/Helldivers-2-SourceGen/Helldivers-2-SourceGen.csproj
+++ b/src/Helldivers-2-SourceGen/Helldivers-2-SourceGen.csproj
@@ -18,13 +18,13 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
-
+
+
+
diff --git a/src/Helldivers-2-Sync/Helldivers-2-Sync.csproj b/src/Helldivers-2-Sync/Helldivers-2-Sync.csproj
index bcb6843..a3ff309 100644
--- a/src/Helldivers-2-Sync/Helldivers-2-Sync.csproj
+++ b/src/Helldivers-2-Sync/Helldivers-2-Sync.csproj
@@ -6,11 +6,10 @@
-
-
-
-
-
+
+
+
+
diff --git a/src/Helldivers-2-Sync/Hosted/ArrowHeadSyncService.cs b/src/Helldivers-2-Sync/Hosted/ArrowHeadSyncService.cs
index 3c9a6e1..9f36ea5 100644
--- a/src/Helldivers-2-Sync/Hosted/ArrowHeadSyncService.cs
+++ b/src/Helldivers-2-Sync/Hosted/ArrowHeadSyncService.cs
@@ -53,7 +53,6 @@ private static partial void LogFailedToLoadTranslation(ILogger logger, Exception
///
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
-
var delay = TimeSpan.FromSeconds(configuration.Value.IntervalSeconds);
LogRunAtInterval(logger, delay);
@@ -113,11 +112,12 @@ private async Task SynchronizeAsync(IServiceProvider services, CancellationToken
cancellationToken
);
- var spaceStations = await configuration.Value.SpaceStations.ToAsyncEnumerable().ToDictionaryAwaitAsync(ValueTask.FromResult, async key =>
- await DownloadTranslations(
- async language => await api.LoadSpaceStations(season, key, language, cancellationToken),
- cancellationToken
- ), cancellationToken: cancellationToken);
+ var spaceStations = await configuration.Value.SpaceStations.ToAsyncEnumerable().ToDictionaryAsync(
+ static (key, _) => ValueTask.FromResult(key), async (key, stoppingToken) =>
+ await DownloadTranslations(
+ async language => await api.LoadSpaceStations(season, key, language, stoppingToken),
+ stoppingToken
+ ), cancellationToken: cancellationToken);
await storage.UpdateStores(
rawWarId,
@@ -152,7 +152,7 @@ private async Task>> DownloadTranslations(Fun
return new KeyValuePair?>(language, null);
}
})
- .SelectAwait(async task => await task)
+ .Select(async (task, stoppingToken) => await task.WaitAsync(stoppingToken))
.Where(pair => pair.Value is not null)
.ToDictionaryAsync(pair => pair.Key, pair => pair.Value.GetValueOrDefault(),
cancellationToken: cancellationToken);