SHA256
Add License Exception
This commit is contained in:
16 files changed
+1038
-994
No files matched your search
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using FFmpeg.AutoGen;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public enum Codec
|
||||
{
|
||||
H264, H265, VP9, AV1, VVC
|
||||
}
|
||||
|
||||
internal static class CodecUtil
|
||||
{
|
||||
public static readonly Dictionary<Codec, AVCodecID> AudioCodecMatch = new()
|
||||
{
|
||||
[Codec.H264] = AVCodecID.AV_CODEC_ID_AAC,
|
||||
[Codec.H265] = AVCodecID.AV_CODEC_ID_AAC,
|
||||
[Codec.VP9] = AVCodecID.AV_CODEC_ID_OPUS,
|
||||
[Codec.AV1] = AVCodecID.AV_CODEC_ID_OPUS,
|
||||
[Codec.VVC] = AVCodecID.AV_CODEC_ID_OPUS
|
||||
};
|
||||
|
||||
public static readonly Dictionary<AVCodecID, List<int>> AvailableSampleRate = new()
|
||||
{
|
||||
[AVCodecID.AV_CODEC_ID_AAC] = new List<int> { 44100, 48000, 96000 },
|
||||
[AVCodecID.AV_CODEC_ID_OPUS] = new List<int> { 48000 }
|
||||
};
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using MelonLoader;
|
||||
using MelonLoader.Utils;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
public class GlobalConfig
|
||||
{
|
||||
public string? OutputDirectory { get; set; }
|
||||
}
|
||||
|
||||
public static class GlobalSettings
|
||||
{
|
||||
private static string SettingsFilePath =>
|
||||
Path.Combine(MelonEnvironment.GameRootDirectory, "UserData", "ADOFAIRenderer", "global_settings.json");
|
||||
|
||||
public static GlobalConfig Current { get; set; } = new();
|
||||
|
||||
public static string DefaultOutputDirectory =>
|
||||
Path.Combine(MelonEnvironment.GameRootDirectory, "Render");
|
||||
|
||||
public static string EffectiveOutputDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Current.OutputDirectory) && Directory.Exists(Current.OutputDirectory))
|
||||
{
|
||||
return Current.OutputDirectory;
|
||||
}
|
||||
|
||||
return DefaultOutputDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
static GlobalSettings()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(SettingsFilePath))
|
||||
{
|
||||
var json = File.ReadAllText(SettingsFilePath);
|
||||
Current = JsonConvert.DeserializeObject<GlobalConfig>(json) ?? new GlobalConfig();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Warning($"[GlobalSettings] Failed to load global settings: {ex.Message}");
|
||||
}
|
||||
|
||||
Current = new GlobalConfig();
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir = Path.GetDirectoryName(SettingsFilePath);
|
||||
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(Current, Formatting.Indented);
|
||||
File.WriteAllText(SettingsFilePath, json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Warning($"[GlobalSettings] Failed to save global settings: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MelonLoader;
|
||||
using MelonLoader.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
internal class RenderPreset
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public RenderConfig Config { get; set; } = null!;
|
||||
}
|
||||
|
||||
internal static class PresetManager
|
||||
{
|
||||
private static string GetPresetsDirectory()
|
||||
{
|
||||
return Path.Combine(MelonEnvironment.GameRootDirectory, "UserData", "ADOFAIRenderer", "Presets");
|
||||
}
|
||||
|
||||
private static string GetSafeFileName(string name)
|
||||
{
|
||||
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_'));
|
||||
}
|
||||
|
||||
public static void SavePreset(string name, RenderConfig config)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentException("Preset name cannot be empty.");
|
||||
}
|
||||
|
||||
string dir = GetPresetsDirectory();
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
var preset = new RenderPreset
|
||||
{
|
||||
Name = name,
|
||||
Config = config
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(preset, Formatting.Indented);
|
||||
string safeName = GetSafeFileName(name);
|
||||
string filePath = Path.Combine(dir, safeName + ".json");
|
||||
File.WriteAllText(filePath, json);
|
||||
}
|
||||
|
||||
public static List<RenderPreset> GetPresets()
|
||||
{
|
||||
var presets = new List<RenderPreset>();
|
||||
var dir = GetPresetsDirectory();
|
||||
|
||||
if (!Directory.Exists(dir)) return presets;
|
||||
|
||||
try
|
||||
{
|
||||
var files = Directory.GetFiles(dir, "*.json");
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(file);
|
||||
var jObject = JsonConvert.DeserializeObject<JObject>(json);
|
||||
if (jObject == null) continue;
|
||||
|
||||
var configToken = jObject["Config"];
|
||||
if (configToken is JObject configObj)
|
||||
{
|
||||
TryChangeKey(configObj, "DelayAfterLevelEnd", "DelayAfterEnd");
|
||||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
|
||||
var preset = jObject.ToObject<RenderPreset>();
|
||||
if (preset != null && !string.IsNullOrEmpty(preset.Name))
|
||||
{
|
||||
presets.Add(preset);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Warning($"Error loading preset file '{Path.GetFileName(file)}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Error($"Error retrieving preset list: {ex.Message}");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var dir = GetPresetsDirectory();
|
||||
var safeName = GetSafeFileName(name);
|
||||
var filePath = Path.Combine(dir, safeName + ".json");
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public enum RateControlMode
|
||||
{
|
||||
CBR,
|
||||
VBR,
|
||||
CQP
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using ADOFAIRenderer.Util.FFmpeg;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
Reference in new issue
Block a user