diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index f56d754..839232d 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -43,8 +43,8 @@ jobs: with: name: sync-artifacts path: | - v1/*.json - v2/*.json + ci/v1/*.json + ci/v2/*.json sync.log - name: Capture error log diff --git a/.gitignore b/.gitignore index 4a2a20a..1a5389f 100644 --- a/.gitignore +++ b/.gitignore @@ -370,3 +370,6 @@ docs/README.md # Ignore OpenAPI documents docs/openapi/*.json + +# Ignore CI files +/ci/ diff --git a/src/Helldivers-2-CI/Program.cs b/src/Helldivers-2-CI/Program.cs index 720f0f1..b02f8b8 100644 --- a/src/Helldivers-2-CI/Program.cs +++ b/src/Helldivers-2-CI/Program.cs @@ -66,16 +66,17 @@ await Task.WhenAll([ var dispatchesv2 = await app.Services.GetRequiredService>().AllAsync(maxRuntime.Token); var store = await app.Services.GetRequiredService>().AllAsync(maxRuntime.Token); -Directory.CreateDirectory("v1"); -Directory.CreateDirectory("v2"); +Directory.CreateDirectory("ci"); +Directory.CreateDirectory("ci/v1"); +Directory.CreateDirectory("ci/v2"); var options = new JsonSerializerOptions { WriteIndented = true }; -await File.WriteAllBytesAsync("v1/assignments.json", JsonSerializer.SerializeToUtf8Bytes(assignments, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v1/campaigns.json", JsonSerializer.SerializeToUtf8Bytes(campaigns, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v1/dispatches.json", JsonSerializer.SerializeToUtf8Bytes(dispatchesv1, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v1/planets.json", JsonSerializer.SerializeToUtf8Bytes(planets, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v1/war.json", JsonSerializer.SerializeToUtf8Bytes(war, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v2/dispatches.json", JsonSerializer.SerializeToUtf8Bytes(dispatchesv2, options), maxRuntime.Token); -await File.WriteAllBytesAsync("v2/space-stations.json", JsonSerializer.SerializeToUtf8Bytes(store, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v1/assignments.json", JsonSerializer.SerializeToUtf8Bytes(assignments, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v1/campaigns.json", JsonSerializer.SerializeToUtf8Bytes(campaigns, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v1/dispatches.json", JsonSerializer.SerializeToUtf8Bytes(dispatchesv1, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v1/planets.json", JsonSerializer.SerializeToUtf8Bytes(planets, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v1/war.json", JsonSerializer.SerializeToUtf8Bytes(war, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v2/dispatches.json", JsonSerializer.SerializeToUtf8Bytes(dispatchesv2, options), maxRuntime.Token); +await File.WriteAllBytesAsync("ci/v2/space-stations.json", JsonSerializer.SerializeToUtf8Bytes(store, options), maxRuntime.Token); return 0; diff --git a/src/Helldivers-2-Models/json b/src/Helldivers-2-Models/json index 981f296..3d9c0e4 160000 --- a/src/Helldivers-2-Models/json +++ b/src/Helldivers-2-Models/json @@ -1 +1 @@ -Subproject commit 981f296ea526503bf79d59c8ac2c8f24c4dd3684 +Subproject commit 3d9c0e493e4502d01973a87db7bdd636cea060b5 diff --git a/src/Helldivers-2-SourceGen/Parsers/BaseJsonParser.cs b/src/Helldivers-2-SourceGen/Parsers/BaseJsonParser.cs index 6ff839a..34e636e 100644 --- a/src/Helldivers-2-SourceGen/Parsers/BaseJsonParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/BaseJsonParser.cs @@ -15,12 +15,14 @@ public abstract class BaseJsonParser : IJsonParser #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using global::System.Collections.Generic; using global::Helldivers.Models.Domain.Localization; +using global::System.CodeDom.Compiler; namespace Helldivers.Models; public static partial class Static {{ /// Public list of {0} entries from {1} + [GeneratedCode(""Helldivers.SourceGen"", ""1.0.0"")] public static {2} {0} = {3}; }}"; @@ -48,4 +50,23 @@ public SourceText Parse(AdditionalText file, CancellationToken cancellationToken /// Convert the JSON string into C# code that can be injected. /// protected abstract (string Type, string Source) Parse(string json); + + /// + /// Escapes the given JSON value so it remains a valid C# string while attempting to preserve formatting. + /// + protected string EscapeString(string? value) + { + const string tripleQuote = @""""""""; + if (string.IsNullOrWhiteSpace(value)) + return string.Empty; + + if (value.Contains('\n') || value.Contains('"')) + { + value = value?.Replace("\n", "\n\t\t"); + + return $"{tripleQuote}\n\t\t{value}\n\t\t{tripleQuote}"; + } + + return $@"""{value}"""; + } } diff --git a/src/Helldivers-2-SourceGen/Parsers/BiomesParser.cs b/src/Helldivers-2-SourceGen/Parsers/BiomesParser.cs index 3a1df0a..b0bc868 100644 --- a/src/Helldivers-2-SourceGen/Parsers/BiomesParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/BiomesParser.cs @@ -14,7 +14,7 @@ protected override (string Type, string Source) Parse(string json) var builder = new StringBuilder("new Dictionary()\n\t{\n"); var entries = JsonSerializer.Deserialize>>(json)!; foreach (var pair in entries) - builder.AppendLine($@"{'\t'}{'\t'}{{ ""{pair.Key}"", new Helldivers.Models.V1.Planets.Biome(""{pair.Value["name"]}"", ""{pair.Value["description"]}"") }},"); + builder.AppendLine($@"{'\t'}{'\t'}{{ {EscapeString(pair.Key)}, new Helldivers.Models.V1.Planets.Biome({EscapeString(pair.Value["name"])}, {EscapeString(pair.Value["description"])}) }},"); builder.Append("\t}"); return ("IReadOnlyDictionary", builder.ToString()); diff --git a/src/Helldivers-2-SourceGen/Parsers/EnvironmentalsParser.cs b/src/Helldivers-2-SourceGen/Parsers/EnvironmentalsParser.cs index b00298c..e7e9dcc 100644 --- a/src/Helldivers-2-SourceGen/Parsers/EnvironmentalsParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/EnvironmentalsParser.cs @@ -15,7 +15,7 @@ protected override (string Type, string Source) Parse(string json) var builder = new StringBuilder("new Dictionary()\n\t{\n"); var entries = JsonSerializer.Deserialize>>(json)!; foreach (var pair in entries) - builder.AppendLine($@"{'\t'}{'\t'}{{ ""{pair.Key}"", new Helldivers.Models.V1.Planets.Hazard(""{pair.Value["name"]}"", ""{pair.Value["description"]}"") }},"); + builder.AppendLine($@"{'\t'}{'\t'}{{ {EscapeString(pair.Key)}, new Helldivers.Models.V1.Planets.Hazard({EscapeString(pair.Value["name"])}, {EscapeString(pair.Value["description"])}) }},"); builder.Append("\t}"); return ("IReadOnlyDictionary", builder.ToString()); diff --git a/src/Helldivers-2-SourceGen/Parsers/FactionsParser.cs b/src/Helldivers-2-SourceGen/Parsers/FactionsParser.cs index 9b4cc0a..28e8dc6 100644 --- a/src/Helldivers-2-SourceGen/Parsers/FactionsParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/FactionsParser.cs @@ -14,7 +14,7 @@ protected override (string Type, string Source) Parse(string json) var builder = new StringBuilder("new Dictionary()\n\t{\n"); var entries = JsonSerializer.Deserialize>(json)!; foreach (var pair in entries) - builder.AppendLine($@"{'\t'}{'\t'}{{ {pair.Key}, ""{pair.Value}"" }},"); + builder.AppendLine($@"{'\t'}{'\t'}{{ {pair.Key}, {EscapeString(pair.Value)} }},"); builder.Append("\t}"); return ("IReadOnlyDictionary", builder.ToString()); diff --git a/src/Helldivers-2-SourceGen/Parsers/PlanetRegionsParser.cs b/src/Helldivers-2-SourceGen/Parsers/PlanetRegionsParser.cs index bb5eaf6..16c86ce 100644 --- a/src/Helldivers-2-SourceGen/Parsers/PlanetRegionsParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/PlanetRegionsParser.cs @@ -21,10 +21,8 @@ protected override (string Type, string Source) Parse(string json) string? description = property.Value.GetProperty("description").GetString(); if (string.IsNullOrWhiteSpace(description)) description = "null"; - else - description = $@"""{description}"""; - builder.AppendLine($@"{'\t'}{'\t'}{{ {index}, (""{name}"", {description}) }},"); + builder.AppendLine($@"{'\t'}{'\t'}{{ {index}, ({EscapeString(name)}, {EscapeString(description)}) }},"); } builder.Append("\t}"); diff --git a/src/Helldivers-2-SourceGen/Parsers/PlanetsParser.cs b/src/Helldivers-2-SourceGen/Parsers/PlanetsParser.cs index 30a8ea3..46b3a23 100644 --- a/src/Helldivers-2-SourceGen/Parsers/PlanetsParser.cs +++ b/src/Helldivers-2-SourceGen/Parsers/PlanetsParser.cs @@ -27,10 +27,10 @@ protected override (string Type, string Source) Parse(string json) .Value .GetProperty("environmentals") .EnumerateArray() - .Select(prop => $@"""{prop.GetString()!}""") + .Select(prop => EscapeString(prop.GetString())) .ToList(); - builder.AppendLine($@"{'\t'}{'\t'}{{ {index}, (LocalizedMessage.FromStrings([{string.Join(", ", names.Select(pair => $@"[""{pair.Key}"", ""{pair.Value}""]"))}]), ""{sector}"", ""{biome}"", [{string.Join(", ", environmentals)}]) }},"); + builder.AppendLine($@"{'\t'}{'\t'}{{ {index}, (LocalizedMessage.FromStrings([{string.Join(", ", names.Select(pair => $@"[{EscapeString(pair.Key)}, {EscapeString(pair.Value)}]"))}]), {EscapeString(sector)}, {EscapeString(biome)}, [{string.Join(", ", environmentals)}]) }},"); } builder.Append("\t}");