From 830197385d8241d19e45b4f5dbca1e42453b994e Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Sun, 2 Mar 2025 13:11:10 -0600 Subject: [PATCH] Add meta and settings json --- .gitmodules | 3 ++ ALttPDoorRandomizer | 1 - ALttPRandomizer/Azure/AzureStorage.cs | 4 +++ ALttPRandomizer/JsonOptions.cs | 15 ++++++++ ALttPRandomizer/Program.cs | 3 +- ALttPRandomizer/Randomizer.cs | 49 ++++++++++++++++++++++---- ALttPRandomizer/Service/SeedService.cs | 25 ++++++++++--- BaseRandomizer | 1 + Dockerfile | 4 +-- 9 files changed, 89 insertions(+), 16 deletions(-) delete mode 160000 ALttPDoorRandomizer create mode 100644 ALttPRandomizer/JsonOptions.cs create mode 160000 BaseRandomizer diff --git a/.gitmodules b/.gitmodules index eea54aa..821fa2e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "ALttPDoorRandomizer"] path = ALttPDoorRandomizer url = https://github.com/ardnaxelarak/ALttPDoorRandomizer +[submodule "BaseRandomizer"] + path = BaseRandomizer + url = https://github.com/ardnaxelarak/ALttPDoorRandomizer diff --git a/ALttPDoorRandomizer b/ALttPDoorRandomizer deleted file mode 160000 index 897f248..0000000 --- a/ALttPDoorRandomizer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 897f248c25e948ac8a25918b427528fb0b93b053 diff --git a/ALttPRandomizer/Azure/AzureStorage.cs b/ALttPRandomizer/Azure/AzureStorage.cs index 6cea835..d6da412 100644 --- a/ALttPRandomizer/Azure/AzureStorage.cs +++ b/ALttPRandomizer/Azure/AzureStorage.cs @@ -19,6 +19,10 @@ await BlobClient.UploadBlobAsync(name, data); } + public async Task UploadFile(string name, BinaryData data) { + await BlobClient.UploadBlobAsync(name, data); + } + public async Task UploadFileAndDelete(string name, string filepath) { using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { this.Logger.LogDebug("Uploading file {filepath} -> {name}", filepath, name); diff --git a/ALttPRandomizer/JsonOptions.cs b/ALttPRandomizer/JsonOptions.cs new file mode 100644 index 0000000..e9f7dae --- /dev/null +++ b/ALttPRandomizer/JsonOptions.cs @@ -0,0 +1,15 @@ +namespace ALttPRandomizer { + using System.Text.Json; + using System.Text.Json.Serialization; + + public static class JsonOptions { + public static JsonSerializerOptions Default = new JsonSerializerOptions() { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + }.WithStringEnum(); + + public static JsonSerializerOptions WithStringEnum(this JsonSerializerOptions options) { + options.Converters.Add(new JsonStringEnumConverter()); + return options; + } + } +} diff --git a/ALttPRandomizer/Program.cs b/ALttPRandomizer/Program.cs index 54aa9cf..4df6875 100644 --- a/ALttPRandomizer/Program.cs +++ b/ALttPRandomizer/Program.cs @@ -40,8 +40,7 @@ }); }); - builder.Services.AddControllers().AddJsonOptions(x => - x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())); + builder.Services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.WithStringEnum()); builder.Services.AddSwaggerGen(); var options = new DefaultAzureCredentialOptions(); diff --git a/ALttPRandomizer/Randomizer.cs b/ALttPRandomizer/Randomizer.cs index 85d6831..6f2fd76 100644 --- a/ALttPRandomizer/Randomizer.cs +++ b/ALttPRandomizer/Randomizer.cs @@ -5,9 +5,11 @@ using ALttPRandomizer.Settings; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; + using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; + using System.Text.Json; using System.Threading.Tasks; public class Randomizer { @@ -48,6 +50,8 @@ args.Add("--outputname"); args.Add(id); + args.Add("--spoiler=json"); + args.Add("--reduce_flashing"); args.Add("--quickswap"); @@ -95,7 +99,7 @@ if (exitcode != 0) { this.GenerationFailed(id, exitcode); } else { - await this.GenerationSucceeded(id); + await this.GenerationSucceeded(id, settings); } }; } @@ -106,19 +110,30 @@ } } - private async Task GenerationSucceeded(string id) { + private async Task GenerationSucceeded(string id, SeedSettings settings) { var rom = Path.Join(Path.GetTempPath(), string.Format("OR_{0}.sfc", id)); var bpsIn = Path.Join(Path.GetTempPath(), string.Format("OR_{0}.bps", id)); var bpsOut = string.Format("{0}/patch.bps", id); - - var spoilerIn = Path.Join(Path.GetTempPath(), string.Format("OR_{0}_Spoiler.txt", id)); - var spoilerOut = string.Format("{0}/spoiler.txt", id); - var uploadPatch = this.AzureStorage.UploadFileAndDelete(bpsOut, bpsIn); + + var spoilerIn = Path.Join(Path.GetTempPath(), string.Format("OR_{0}_Spoiler.json", id)); + var spoilerOut = string.Format("{0}/spoiler.json", id); var uploadSpoiler = this.AzureStorage.UploadFileAndDelete(spoilerOut, spoilerIn); - await Task.WhenAll(uploadPatch, uploadSpoiler); + var metaIn = Path.Join(Path.GetTempPath(), string.Format("OR_{0}_Meta.json", id)); + var metaOut = string.Format("{0}/meta.json", id); + var meta = this.ProcessMetadata(metaIn); + var uploadMeta = this.AzureStorage.UploadFile(metaOut, new BinaryData(meta)); + + var settingsJson = JsonSerializer.SerializeToDocument(settings, JsonOptions.Default); + var settingsOut = string.Format("{0}/settings.json", id); + var uploadSettings = this.AzureStorage.UploadFile(settingsOut, new BinaryData(settingsJson)); + + await Task.WhenAll(uploadPatch, uploadSpoiler, uploadMeta, uploadSettings); + + this.Logger.LogDebug("Deleting file {filepath}", metaIn); + File.Delete(metaIn); this.Logger.LogDebug("Deleting file {filepath}", rom); File.Delete(rom); @@ -126,6 +141,26 @@ this.Logger.LogDebug("Finished uploading seed id {id}", id); } + private JsonDocument ProcessMetadata(string path) { + JsonDocument orig; + using (var file = File.OpenRead(path)) { + orig = JsonDocument.Parse(file); + } + + + var processed = new Dictionary(); + foreach (var toplevel in orig.RootElement.EnumerateObject()) { + var value = toplevel.Value; + if (value.ValueKind == JsonValueKind.Object && value.TryGetProperty("1", out var p1)) { + processed[toplevel.Name] = p1; + } else { + processed[toplevel.Name] = toplevel.Value; + } + } + + return JsonSerializer.SerializeToDocument(processed, JsonOptions.Default); + } + private void GenerationFailed(string id, int exitcode) { } } diff --git a/ALttPRandomizer/Service/SeedService.cs b/ALttPRandomizer/Service/SeedService.cs index 0effe96..a08ab8f 100644 --- a/ALttPRandomizer/Service/SeedService.cs +++ b/ALttPRandomizer/Service/SeedService.cs @@ -2,6 +2,7 @@ using ALttPRandomizer.Azure; using System; using System.Collections.Generic; + using System.Text.Json; using System.Threading.Tasks; public class SeedService { @@ -11,12 +12,28 @@ private AzureStorage AzureStorage { get; } - public async Task> GetSeed(string seedId) { + public async Task> GetSeed(string seedId) { var files = await this.AzureStorage.GetFiles(seedId); - var result = new Dictionary(); - foreach (var file in files) { - result[file.Key] = Convert.ToBase64String(file.Value.ToMemory().ToArray()); + var result = new Dictionary(); + + if (files.TryGetValue("settings.json", out var settingsData)) { + var json = JsonDocument.Parse(settingsData.ToString()); + result["settings"] = json; + } + + if (files.TryGetValue("meta.json", out var metaData)) { + var json = JsonDocument.Parse(metaData.ToString()); + result["meta"] = json; + } + + if (files.TryGetValue("spoiler.json", out var spoilerData)) { + var json = JsonDocument.Parse(spoilerData.ToString()); + result["spoiler"] = json; + } + + if (files.TryGetValue("patch.bps", out var patchData)) { + result["patch.bps"] = Convert.ToBase64String(patchData.ToArray()); } return result; diff --git a/BaseRandomizer b/BaseRandomizer new file mode 160000 index 0000000..283ece4 --- /dev/null +++ b/BaseRandomizer @@ -0,0 +1 @@ +Subproject commit 283ece402062d523193ef27d026d1ba8036fb5ad diff --git a/Dockerfile b/Dockerfile index b8a53dd..2fbf9c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,10 +25,10 @@ RUN python3 -m ensurepip --upgrade WORKDIR /randomizer COPY alttp.sfc . -COPY ALttPDoorRandomizer/resources/app/meta/manifests/pip_requirements.txt requirements.txt +COPY BaseRandomizer/resources/app/meta/manifests/pip_requirements.txt requirements.txt RUN python3 -m pip install -r requirements.txt -COPY ALttPDoorRandomizer/ . +COPY BaseRandomizer/ . WORKDIR /app COPY --from=build /app/publish .