[O] 配置文件读写相关优化

close #87
This commit is contained in:
Clansty
2025-11-07 15:14:31 +08:00
parent 49b9ac30ae
commit c7ea71ca70
6 changed files with 128 additions and 21 deletions

View File

@@ -18,6 +18,8 @@ public static class ConfigLoader
public static Config.Config Config => config;
private static string configText;
public static bool LoadConfig(Assembly modsAssembly)
{
Utility.LogFunction = MelonLogger.Msg;
@@ -43,7 +45,7 @@ public static class ConfigLoader
return false;
}
var configText = File.ReadAllText(ConfigFile);
configText = File.ReadAllText(ConfigFile);
var configView = new ConfigView(configText);
var configVersion = ConfigMigrationManager.Instance.GetVersion(configView);
if (configVersion != ConfigMigrationManager.Instance.LatestVersion)
@@ -60,6 +62,8 @@ public static class ConfigLoader
public static void SaveConfig(string lang)
{
var newText = SerailizeCurrentConfig(lang);
if (newText == configText) return;
File.WriteAllText(ConfigFile, SerailizeCurrentConfig(lang));
}
@@ -74,10 +78,10 @@ public static class ConfigLoader
private static IDictionary<string, string> GenerateExamples()
{
var examples = new Dictionary<string, string>();
foreach (var lang in (string[]) ["en", "zh"])
foreach (var lang in (string[])["en", "zh"])
{
examples[lang] = SerailizeCurrentConfig(lang);
}
return examples;
}
}
}

View File

@@ -0,0 +1,52 @@
using HarmonyLib;
using Main;
using UnityEngine;
namespace AquaMai.Core.Helpers;
public class InvalidConfigAlert : MonoBehaviour
{
[HarmonyPostfix]
[HarmonyPatch(typeof(GameMainObject), "Awake")]
public static void OnGameMainObjectAwake(GameMainObject __instance)
{
Destroy(__instance);
var go = new GameObject("配置错误提示组件");
go.AddComponent<InvalidConfigAlert>();
}
public const string ConfigNotFoundMessage = """
AquaMai
AquaMai.zh.toml AquaMai.toml
使 MaiChartManager
退
AquaMai Configuration Not Found!
Example configuration files have been generated and saved to AquaMai.en.toml
Please rename them to AquaMai.toml and make the necessary changes
Now please exit the game
""";
public const string ConfigCorruptedMessage = """
AquaMai
退
AquaMai Configuration Corrupted! An error occurred while reading the configuration file
Please exit the game and check if the configuration file has any format errors
Now please exit the game
""";
public static string message = "";
private void OnGUI()
{
GUIStyle style = new GUIStyle(GUI.skin.label)
{
fontSize = 25,
alignment = TextAnchor.UpperLeft,
wordWrap = true,
};
GUI.Label(new Rect(50, 50, Screen.width / 2f, Screen.height / 1920f * 450f), message, style);
}
}

View File

@@ -280,15 +280,6 @@ namespace AquaMai.Core.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to SSS+ =&gt; DXRating += {0}.
/// </summary>
public static string RatingUpWhenSSSp {
get {
return ResourceManager.GetString("RatingUpWhenSSSp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AP =&gt; DXRating += {0}.
/// </summary>
@@ -298,6 +289,15 @@ namespace AquaMai.Core.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to SSS+ =&gt; DXRating += {0}.
/// </summary>
public static string RatingUpWhenSSSp {
get {
return ResourceManager.GetString("RatingUpWhenSSSp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Repeat end time cannot be less than repeat start time.
/// </summary>
@@ -473,6 +473,19 @@ namespace AquaMai.Core.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to ==================================================================!!!
///Unable to save configuration file.
///Maybe the configuration file directory is read-only or other problems
///The local configuration file may not reflect the latest added options
///=====================================================================.
/// </summary>
public static string UnableSaveConfig {
get {
return ResourceManager.GetString("UnableSaveConfig", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unable to establish TLS connection to title server, will use plain HTTP instead..
/// </summary>

View File

@@ -172,4 +172,11 @@ Press {2} to switch block or exit adjustment mode</value>
<data name="AutoplayWasUsed" xml:space="preserve">
<value>Autoplay was used, score will not be saved.</value>
</data>
<data name="UnableSaveConfig" xml:space="preserve">
<value>==================================================================!!!
Unable to save configuration file.
Maybe the configuration file directory is read-only or other problems
The local configuration file may not reflect the latest added options
=====================================================================</value>
</data>
</root>

View File

@@ -165,4 +165,10 @@
<data name="AutoplayWasUsed" xml:space="preserve">
<value>Autoplay曾开启过本曲成绩不会被上传。</value>
</data>
<data name="UnableSaveConfig" xml:space="preserve">
<value>=============================================!!!
无法保存配置文件。或许是配置文件目录只读或者其他问题
本地的配置文件可能无法反应最新添加的选项
================================================</value>
</data>
</root>

View File

@@ -136,21 +136,46 @@ public class Startup
public static void Initialize(Assembly modsAssembly, HarmonyLib.Harmony harmony)
{
MelonLogger.Msg("Loading mod settings...");
var configLoaded = ConfigLoader.LoadConfig(modsAssembly);
var lang = ResolveLocale();
if (configLoaded)
{
ConfigLoader.SaveConfig(lang); // Re-save the config as soon as possible
}
_harmony = harmony;
bool configLoaded;
try
{
configLoaded = ConfigLoader.LoadConfig(modsAssembly);
}
catch (Exception ex)
{
MelonLogger.Error($"Failed to load config file: {ex}");
InvalidConfigAlert.message = InvalidConfigAlert.ConfigCorruptedMessage;
ApplyPatch(typeof(InvalidConfigAlert));
return;
}
var lang = ResolveLocale();
// Init locale with patching C# runtime
// https://stackoverflow.com/questions/1952638/single-assembly-multi-language-windows-forms-deployment-ilmerge-and-satellite-a
ApplyPatch(typeof(I18nSingleAssemblyHook));
Locale.Culture = CultureInfo.GetCultureInfo(lang); // Must be called after I18nSingleAssemblyHook patched
if (configLoaded)
{
try
{
ConfigLoader.SaveConfig(lang); // Re-save the config as soon as possible
}
catch (Exception ex)
{
MelonLogger.Warning(ex);
MelonLogger.Warning("\n" + Locale.UnableSaveConfig);
}
}
else
{
InvalidConfigAlert.message = InvalidConfigAlert.ConfigNotFoundMessage;
ApplyPatch(typeof(InvalidConfigAlert));
return;
}
// The patch list is ordered
List<Type> wantedPatches = [];
@@ -213,4 +238,4 @@ public class Startup
GuiSizes.SetupStyles();
}
}
}
}