You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.8 KiB

using Newtonsoft.Json;
namespace CMSGame
{
/// <summary>
/// 游戏设置持久化
/// </summary>
public partial class GameSettings : Node
{
protected Dictionary<Type, SettingsBase> CurrentSettings = new();
protected Dictionary<Type, SettingsBase> OriginalSettings = new();
protected Dictionary<Type, string> SettingsPaths = new();
public BattleSettings BattleSettings => GetSettings<BattleSettings>();
public VideoSettings VideoSettings => GetSettings<VideoSettings>();
public AudioSettings AudioSettings => GetSettings<AudioSettings>();
public GameSettings()
{
RegisterAllSettings();
}
public override void _Ready()
{
MakeDirectories();
LoadAllSettings();
}
protected void RegisterAllSettings()
{
RegisterSettings<BattleSettings>("BattleSettings.json");
RegisterSettings<VideoSettings>("VideoSettings.json");
RegisterSettings<AudioSettings>("AudioSettings.json");
}
protected void RegisterSettings<TSettings>(string filename) where TSettings : SettingsBase, new()
{
var defaultSettings = new TSettings();
CurrentSettings.Add(typeof(TSettings), defaultSettings);
SettingsPaths.Add(typeof(TSettings), new GodotPath($"user://Settings/{filename}"));
}
protected void LoadAllSettings()
{
foreach (var settingsType in SettingsPaths.Keys)
{
LoadSettings(settingsType);
}
}
public override void _ExitTree()
{
foreach (var settingsType in SettingsPaths.Keys)
{
if (!OriginalSettings.ContainsKey(settingsType) || OriginalSettings[settingsType] != CurrentSettings[settingsType])
{
SaveSettings(settingsType);
}
}
}
private static void MakeDirectories()
{
DirAccess.MakeDirRecursiveAbsolute("user://Settings/");
}
private void LoadSettings(Type settingsType)
{
string settingsText = ReadFileAsString(SettingsPaths[settingsType]);
var settings = JsonConvert.DeserializeObject(settingsText, settingsType);
if (settings != null)
{
OriginalSettings[settingsType] = (SettingsBase)settings;
CurrentSettings[settingsType] = (SettingsBase)settings;
}
}
public TSettings GetSettings<TSettings>() where TSettings : SettingsBase, new()
{
return (TSettings)CurrentSettings[typeof(TSettings)];
}
private static string ReadFileAsString(string path)
{
if (FileAccess.FileExists(path))
{
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
return file.GetAsText();
}
return "null";
}
private void SaveSettings(Type settingsType)
{
string settingsText = JsonConvert.SerializeObject(CurrentSettings[settingsType]);
using var file = FileAccess.Open(SettingsPaths[settingsType], FileAccess.ModeFlags.Write);
file.StoreString(settingsText);
}
}
public record class SettingsBase
{
}
public record class BattleSettings : SettingsBase
{ }
public record class VideoSettings : SettingsBase
{ }
public record class AudioSettings : SettingsBase
{
/// <summary>
/// 音乐音量
/// </summary>
public double MusicVolume = 80;
/// <summary>
/// 音效音量
/// </summary>
public double SoundEffectVolume = 80;
}
}