using System.Collections.Generic; using System.IO; using Managers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; namespace Configs { /// /// 配置管理器,采用单例模式,负责读取、修改、存储应用程序配置。 /// 继承自 Utils.Singleton 和 ILaunchManager。 /// public class ConfigManager : Utils.Singleton, ILaunchManager { /// /// 配置文件名 /// private const string CONFIG_FILE_NAME = "app_config.json"; /// /// 完整的配置文件路径 /// Application.persistentDataPath 在PC上是 C:/Users/用户名/AppData/LocalLow/公司名/项目名/, /// 在Android/iOS上是持久存储路径。 /// private readonly string _configFilePath; /// /// 存储配置数据的字典。使用 JToken 允许存储任意 JSON 类型(基本类型、对象、数组)。 /// private Dictionary _configData; /// /// 私有构造函数,由 Singleton 基类调用。 /// public ConfigManager() { _configFilePath = Path.Combine(Application.persistentDataPath, CONFIG_FILE_NAME); _configData = new Dictionary(); Debug.Log($"ConfigManager initialized. Config file path: {_configFilePath}"); } public string StepDescription => "载入配置文件"; /// /// 初始化配置管理器,加载配置文件。 /// 如果配置文件不存在,将创建一个默认配置。 /// public void Init() { LoadConfig(); } /// /// 清理配置管理器,释放内存中的配置数据。 /// 注意:此方法不会自动保存配置。如果需要在清理前保存,请手动调用 Save()。 /// public void Clear() { _configData.Clear(); } /// /// 从配置文件加载配置数据到内存。 /// 如果文件不存在,则创建默认配置并保存。 /// private void LoadConfig() { if (File.Exists(_configFilePath)) { try { string json = File.ReadAllText(_configFilePath); _configData = JsonConvert.DeserializeObject>(json); } catch (JsonException ex) { Debug.LogError( $"ConfigManager: Failed to deserialize config file. Creating default config. Error: {ex.Message}"); CreateDefaultConfig(); SaveConfig(); // 保存默认配置 } catch (IOException ex) { Debug.LogError( $"ConfigManager: Failed to read config file. Creating default config. Error: {ex.Message}"); CreateDefaultConfig(); SaveConfig(); // 保存默认配置 } } else { Debug.Log("ConfigManager: Config file not found. Creating default config."); CreateDefaultConfig(); SaveConfig(); // 保存默认配置 } } /// /// 创建一个默认的空配置或包含初始值的配置。 /// private void CreateDefaultConfig() { _configData = new Dictionary(); SetValue("playerAffiliation","player"); SetValue("outsideDimension","DefaultOutsideDimension"); SetValue("insideDimension","DefaultInsideDimension"); } /// /// 将内存中的配置数据保存到配置文件。 /// public void SaveConfig() { try { // 使用 Formatting.Indented 使 JSON 文件更具可读性 string json = JsonConvert.SerializeObject(_configData, Formatting.Indented); File.WriteAllText(_configFilePath, json); Debug.Log("ConfigManager: Configuration saved successfully."); } catch (JsonException ex) { Debug.LogError($"ConfigManager: Failed to serialize config data. Error: {ex.Message}"); } catch (IOException ex) { Debug.LogError($"ConfigManager: Failed to write config file. Error: {ex.Message}"); } } /// /// 获取指定键的配置值。 /// /// 值的目标类型。 /// 配置项的键。 /// 如果键不存在或类型转换失败,返回的默认值。 /// 配置值或默认值。 public T GetValue(string key, T defaultValue = default(T)) { if (_configData.TryGetValue(key, out JToken jToken)) { try { // JToken.ToObject() 能够智能地将 JToken 转换为目标类型 T return jToken.ToObject(); } catch (JsonException ex) { Debug.LogWarning( $"ConfigManager: Failed to convert value for key '{key}' to type '{typeof(T).Name}'. " + $"Returning default value. Error: {ex.Message}"); return defaultValue; } } Debug.LogWarning($"ConfigManager: Key '{key}' not found. Returning default value '{defaultValue}'."); return defaultValue; } /// /// 设置指定键的配置值。 /// /// 值的类型。 /// 配置项的键。 /// 要设置的值。 public void SetValue(string key, T value) { if (string.IsNullOrEmpty(key)) { Debug.LogError("ConfigManager: Cannot set value with an empty or null key."); return; } try { // JToken.FromObject(value) 能够将任何对象转换为 JToken _configData[key] = JToken.FromObject(value); Debug.Log( $"ConfigManager: Value for key '{key}' set to '{value}'. Remember to call SaveConfig() to persist changes."); } catch (JsonException ex) { Debug.LogError( $"ConfigManager: Failed to convert value '{value}' for key '{key}' to JToken. Error: {ex.Message}"); } } /// /// 检查配置中是否存在某个键。 /// /// 要检查的键。 /// 如果存在该键,则为 true;否则为 false。 public bool ContainsKey(string key) { return _configData.ContainsKey(key); } /// /// 移除指定键的配置项。 /// /// 要移除的键。 /// 如果成功移除,则为 true;否则为 false。 public bool RemoveKey(string key) { if (_configData.Remove(key)) { Debug.Log($"ConfigManager: Key '{key}' removed. Remember to call SaveConfig() to persist changes."); return true; } Debug.LogWarning($"ConfigManager: Attempted to remove non-existent key '{key}'."); return false; } /// /// 直接获取原始的 JToken 值,适用于处理复杂或嵌套的 JSON 结构。 /// /// 配置项的键。 /// 对应的 JToken;如果键不存在,则为 null。 public JToken GetRawJToken(string key) { _configData.TryGetValue(key, out JToken jToken); return jToken; } } }