From 6d2d7785b932d937dd4e56c8b1f3bfe99fef34f597ae85f41e3136377d2134da Mon Sep 17 00:00:00 2001 From: copecone Date: Mon, 17 Aug 2026 21:14:23 +0900 Subject: [PATCH] Change `RenderConfig.DelayAfterLevelEnd` to `DelayAfterEnd` --- API/Core.cs | 6 -- API/RenderSession.cs | 49 ++++++++++++ Data/PresetManager.cs | 178 ++++++++++++++++++++++-------------------- Data/RenderConfig.cs | 12 +-- 4 files changed, 148 insertions(+), 97 deletions(-) delete mode 100644 API/Core.cs create mode 100644 API/RenderSession.cs diff --git a/API/Core.cs b/API/Core.cs deleted file mode 100644 index 5a82c7a..0000000 --- a/API/Core.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ADOFAIRenderer.API; - -public class Core -{ - -} \ No newline at end of file diff --git a/API/RenderSession.cs b/API/RenderSession.cs new file mode 100644 index 0000000..95e4d91 --- /dev/null +++ b/API/RenderSession.cs @@ -0,0 +1,49 @@ +using System; +using ADOFAIRenderer.Core; + +namespace ADOFAIRenderer.API; + +/// +/// Fluent builder for configuring and starting a render session. +/// +public class RenderSessionBuilder +{ + private bool _auto = true; + + public enum PatchType { Time, Screen } + private bool _timePatch = true; + private bool _screenPatch = true; + + /// + /// Sets whether automatic rendering is enabled. + /// + /// true to enable automatic rendering; otherwise, false. Default is true. + /// The current instance for method chaining. + public RenderSessionBuilder WithAuto(bool enabled = true) + { + _auto = enabled; + return this; + } + + public RenderSessionBuilder WithPatch(PatchType patchType, bool enabled = true) + { + switch (patchType) + { + case PatchType.Time: _timePatch = enabled; break; + case PatchType.Screen: _screenPatch = enabled; break; + default: throw new ArgumentOutOfRangeException(nameof(patchType), patchType, null); + } + + return this; + } + + /// + /// Applies the configured flags and initiates the render session. + /// + public void Start() + { + RenderFlags.Auto = _auto; + RenderFlags.TimePatch = _timePatch; + RenderFlags.ScreenPatch = _screenPatch; + } +} \ No newline at end of file diff --git a/Data/PresetManager.cs b/Data/PresetManager.cs index ea12f0f..344213a 100644 --- a/Data/PresetManager.cs +++ b/Data/PresetManager.cs @@ -55,102 +55,101 @@ namespace ADOFAIRenderer.Data public static List GetPresets() { var presets = new List(); - string dir = GetPresetsDirectory(); - if (!Directory.Exists(dir)) - { - return presets; - } + var dir = GetPresetsDirectory(); + + if (!Directory.Exists(dir)) return presets; try { - string[] files = Directory.GetFiles(dir, "*.json"); - foreach (string file in files) + var files = Directory.GetFiles(dir, "*.json"); + foreach (var file in files) { try { - string json = File.ReadAllText(file); + var json = File.ReadAllText(file); var jObject = JsonConvert.DeserializeObject(json); - if (jObject != null) + if (jObject == null) continue; + + var configToken = jObject["Config"]; + if (configToken is JObject configObj) { - var configToken = jObject["Config"]; - if (configToken is JObject configObj) - { - // 1. legacy EncodingConfig -> VideoConfig - if (configObj["EncodingConfig"] is JObject oldEncodingConfigObj) - { - configObj["VideoConfig"] ??= oldEncodingConfigObj; - configObj.Remove("EncodingConfig"); - } - - // 2. legacy top-level Codec -> VideoConfig.Codec - var legacyCodecToken = configObj["Codec"]; - if (legacyCodecToken != null && legacyCodecToken.Type != JTokenType.Null) - { - if (configObj["VideoConfig"] == null || configObj["VideoConfig"]!.Type == JTokenType.Null) - { - configObj["VideoConfig"] = new JObject(); - } - - var videoConfigObj = (JObject)configObj["VideoConfig"]!; - videoConfigObj["Codec"] ??= legacyCodecToken; - - configObj.Remove("Codec"); - } - - // 3. legacy top-level Audio properties -> AudioConfig - string[] legacyAudioProps = { "RenderAudio", "AudioSampleRate", "AudioChannels", "AudioBitrate" }; - foreach (var prop in legacyAudioProps) - { - var legacyToken = configObj[prop]; - if (legacyToken != null && legacyToken.Type != JTokenType.Null) - { - if (configObj["AudioConfig"] == null || configObj["AudioConfig"]!.Type == JTokenType.Null) - { - configObj["AudioConfig"] = new JObject(); - } - - var audioConfigObj = (JObject)configObj["AudioConfig"]!; - audioConfigObj[prop] ??= legacyToken; - } - - configObj.Remove(prop); - } - - if (configObj["AudioConfig"] != null && configObj["AudioConfig"]!.Type == JTokenType.Null) - { - configObj.Remove("AudioConfig"); - } - - // 4. legacy top-level Advanced properties -> AdvancedConfig - string[] legacyAdvancedProps = { "RandomSeed", "ProcessAudio", "NonTile" }; - foreach (var prop in legacyAdvancedProps) - { - var legacyToken = configObj[prop]; - if (legacyToken != null && legacyToken.Type != JTokenType.Null) - { - if (configObj["AdvancedConfig"] == null || configObj["AdvancedConfig"]!.Type == JTokenType.Null) - { - configObj["AdvancedConfig"] = new JObject(); - } - - var advancedConfigObj = (JObject)configObj["AdvancedConfig"]!; - advancedConfigObj[prop] ??= legacyToken; - } - - configObj.Remove(prop); - } - - if (configObj["AdvancedConfig"] != null && configObj["AdvancedConfig"]!.Type == JTokenType.Null) - { - configObj.Remove("AdvancedConfig"); - } - } + TryChangeKey(configObj, "DelayAfterLevelEnd", "DelayAfterEnd"); - var preset = jObject.ToObject(); - if (preset != null && !string.IsNullOrEmpty(preset.Name)) + // 1. legacy EncodingConfig -> VideoConfig + if (configObj["EncodingConfig"] is JObject oldEncodingConfigObj) { - presets.Add(preset); + configObj["VideoConfig"] ??= oldEncodingConfigObj; + configObj.Remove("EncodingConfig"); } + + // 2. legacy top-level Codec -> VideoConfig.Codec + var legacyCodecToken = configObj["Codec"]; + if (legacyCodecToken != null && legacyCodecToken.Type != JTokenType.Null) + { + if (configObj["VideoConfig"] == null || configObj["VideoConfig"]!.Type == JTokenType.Null) + { + configObj["VideoConfig"] = new JObject(); + } + + var videoConfigObj = (JObject)configObj["VideoConfig"]!; + videoConfigObj["Codec"] ??= legacyCodecToken; + + configObj.Remove("Codec"); + } + + // 3. legacy top-level Audio properties -> AudioConfig + string[] legacyAudioProps = { "RenderAudio", "AudioSampleRate", "AudioChannels", "AudioBitrate" }; + foreach (var prop in legacyAudioProps) + { + var legacyToken = configObj[prop]; + if (legacyToken != null && legacyToken.Type != JTokenType.Null) + { + if (configObj["AudioConfig"] == null || configObj["AudioConfig"]!.Type == JTokenType.Null) + { + configObj["AudioConfig"] = new JObject(); + } + + var audioConfigObj = (JObject)configObj["AudioConfig"]!; + audioConfigObj[prop] ??= legacyToken; + } + + configObj.Remove(prop); + } + + if (configObj["AudioConfig"] != null && configObj["AudioConfig"]!.Type == JTokenType.Null) + { + configObj.Remove("AudioConfig"); + } + + // 4. legacy top-level Advanced properties -> AdvancedConfig + string[] legacyAdvancedProps = { "RandomSeed", "ProcessAudio", "NonTile" }; + foreach (var prop in legacyAdvancedProps) + { + var legacyToken = configObj[prop]; + if (legacyToken != null && legacyToken.Type != JTokenType.Null) + { + if (configObj["AdvancedConfig"] == null || configObj["AdvancedConfig"]!.Type == JTokenType.Null) + { + configObj["AdvancedConfig"] = new JObject(); + } + + var advancedConfigObj = (JObject)configObj["AdvancedConfig"]!; + advancedConfigObj[prop] ??= legacyToken; + } + + configObj.Remove(prop); + } + + if (configObj["AdvancedConfig"] != null && configObj["AdvancedConfig"]!.Type == JTokenType.Null) + { + configObj.Remove("AdvancedConfig"); + } + } + + var preset = jObject.ToObject(); + if (preset != null && !string.IsNullOrEmpty(preset.Name)) + { + presets.Add(preset); } } catch (Exception ex) @@ -167,6 +166,15 @@ namespace ADOFAIRenderer.Data return presets; } + private static void TryChangeKey(JObject configObj, string keyBefore, string targetKey) + { + var legacyToken = configObj[keyBefore]; + if (legacyToken != null && legacyToken.Type != JTokenType.Null) + configObj[targetKey] = legacyToken; + + configObj.Remove(keyBefore); + } + public static void DeletePreset(string name) { string dir = GetPresetsDirectory(); diff --git a/Data/RenderConfig.cs b/Data/RenderConfig.cs index a8ce42b..7181ac8 100644 --- a/Data/RenderConfig.cs +++ b/Data/RenderConfig.cs @@ -2,7 +2,7 @@ using ADOFAIRenderer.Util.FFmpeg; namespace ADOFAIRenderer.Data { - internal class RenderConfig + public class RenderConfig { public double RenderFPS { get; set; } public double VideoFPS { get; set; } @@ -14,18 +14,18 @@ namespace ADOFAIRenderer.Data public AudioEncodingConfig AudioConfig { get; set; } = new(); public AdvancedConfig AdvancedConfig { get; set; } = new(); - public double DelayAfterLevelEnd { get; set; } + public double DelayAfterEnd { get; set; } public bool ShowJudgementText { get; set; } } - internal class AdvancedConfig + public class AdvancedConfig { public int? RandomSeed { get; set; } = null; public bool ProcessAudio { get; set; } = true; public bool NonTile { get; set; } = false; } - internal class VideoEncodingConfig + public class VideoEncodingConfig { public Codec Codec { get; set; } = Codec.H264; public RateControlMode RateControlMode { get; set; } = RateControlMode.CBR; @@ -35,10 +35,10 @@ namespace ADOFAIRenderer.Data // ReSharper disable once InconsistentNaming public int QP { get; set; } = 18; public double KeyframeInterval { get; set; } = 2.0; - public bool ForceSoftwareEncoder { get; set; } = false; + public bool ForceSoftwareEncoder { get; set; } } - internal class AudioEncodingConfig + public class AudioEncodingConfig { private int _audioSampleRate = 44100; private int _audioChannels = 2;