using System.Collections.Generic; using UnityEngine; using System.IO; [CreateAssetMenu(fileName = "SettingsData", menuName = "Settings/SettingsData", order = 0)] public class SettingsData : ScriptableObject { [Tooltip("Список дефолтных настроек, будет использован при первом запуске или при сбросе")] public List defaultSettings = new List(); public List GetDefaults() { if (defaultSettings != null && defaultSettings.Count > 0) return defaultSettings; // fallback: возвращаем встроенные дефолты return CreateBuiltinDefaults(); } // Создаёт новый GameSettings (клонированный) на основе defaultSettings или встраиваемых дефолтов public GameSettings CreateGameSettings() { var defaults = GetDefaults(); var gs = new GameSettings(); gs.settings = new List(); foreach (var s in defaults) { gs.settings.Add(new SettingOption(s.settingName, new List(s.options), s.defaultIndex, s.type, s.panelId)); } gs.hash = ComputeHash(gs.settings); return gs; } // Создаёт GameSettings на основе встроенных дефолтов (статический helper) public static GameSettings CreateGameSettingsFromDefaults() { var defaults = CreateBuiltinDefaults(); var gs = new GameSettings(); gs.settings = new List(); foreach (var s in defaults) { gs.settings.Add(new SettingOption(s.settingName, new List(s.options), s.defaultIndex, s.type, s.panelId)); } gs.hash = ComputeHash(gs.settings); return gs; } private static int ComputeHash(List settings) { var sb = new System.Text.StringBuilder(); foreach (var option in settings) { sb.Append(option.settingName); foreach (var o in option.options) { sb.Append(o); } } return sb.ToString().GetHashCode(); } public static List CreateBuiltinDefaults() { List settings = new List(); settings.Add(new SettingOption(settingName: "Громкость музыки", options: new List() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }, defaultIndex: 1)); settings.Add(new SettingOption(settingName: "Громкость эффектов", options: new List() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }, defaultIndex: 8)); settings.Add(new SettingOption(settingName: "Громкость голоса", options: new List() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }, defaultIndex: 8)); settings.Add(new SettingOption(settingName: "QR-код для связи", options: new List() { "Telegram", "WhatsApp" ,"Всё"}, defaultIndex: 0)); settings.Add(new SettingOption(settingName: "Игровая тема", options: new List() { "День", "Ночь" }, defaultIndex: 0)); settings.Add(new SettingOption(settingName: "Выдача призов при игре с ботом", options: new List() { "Выдавать", "Не выдавать" }, defaultIndex: 0, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Бесплатная игра", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Показывать контакты администрации", options: new List() { "Вкл", "Выкл" }, defaultIndex: 0, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Быстрая проверка", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Быстрая проверка наличия приза", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Выдавать приз при ошибке", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Вывод ошибки выдачи в меню", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); settings.Add(new SettingOption(settingName: "Вывод информации о суперпризе в меню", options: new List() { "Вкл", "Выкл" }, defaultIndex: 1, type: SettingType.Svitcher)); // Настройки-панели (открываются удержанием) settings.Add(new SettingOption( settingName: "Ввести номер телефона тех-поддержки", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 0)); settings.Add(new SettingOption( settingName: "Ввести номер для связи в WhatsApp", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 1)); settings.Add(new SettingOption( settingName: "Ввести номер для связи в Telegram", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 2)); settings.Add(new SettingOption( settingName: "Задать часоту выдачи специального приза", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 3)); settings.Add(new SettingOption( settingName: "Задать суперприз", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 4)); settings.Add(new SettingOption( settingName: "Настройка персонажа", options: new List() { "" }, defaultIndex: 0, type: SettingType.Panel, panelId: 5)); // Настройки-экшены (выполняются удержанием) settings.Add(new SettingOption( settingName: "Сбросить счетчик монет", options: new List() { "" }, defaultIndex: 0, type: SettingType.Action, panelId: 100)); settings.Add(new SettingOption( settingName: "Сброс статистики призов", options: new List() { "" }, defaultIndex: 0, type: SettingType.Action, panelId: 101)); settings.Add(new SettingOption( settingName: "Сброс прогресса до суперприза", options: new List() { "" }, defaultIndex: 0, type: SettingType.Action, panelId: 102)); return settings; } // Попытка загрузить GameSettings из JSON-файла. Возвращает null при ошибке/отсутствии файла. public GameSettings TryLoadFromFile(string path) { try { if (!File.Exists(path)) return null; string json = File.ReadAllText(path, System.Text.Encoding.UTF8); var gs = JsonUtility.FromJson(json); return gs; } catch (System.Exception e) { Debug.LogWarning($"SettingsData.TryLoadFromFile failed: {e.Message}"); return null; } } // Попытка сохранить GameSettings в файл. Возвращает true при успехе. public bool TrySaveToFile(string path, GameSettings gs) { try { if (gs == null) return false; string json = JsonUtility.ToJson(gs); File.WriteAllText(path, json, System.Text.Encoding.UTF8); return true; } catch (System.Exception e) { Debug.LogError($"SettingsData.TrySaveToFile failed: {e.Message}"); return false; } } // Загрузить из файла или создать дефолтный GameSettings и сохранить его public GameSettings LoadOrCreateFromFile(string path) { var loaded = TryLoadFromFile(path); if (loaded != null) return loaded; var created = CreateGameSettings(); TrySaveToFile(path, created); return created; } // Попытка загрузить GameSettings из файла (статическая, не требует экземпляра SettingsData) public static GameSettings LoadFromFile(string path) { try { if (!File.Exists(path)) return null; string json = File.ReadAllText(path, System.Text.Encoding.UTF8); var gs = JsonUtility.FromJson(json); return gs; } catch (System.Exception e) { Debug.LogWarning($"SettingsData.LoadFromFile failed: {e.Message}"); return null; } } // Сохранить GameSettings в файл (статическая версия) public static bool SaveToFile(string path, GameSettings gs) { try { if (gs == null) return false; string json = JsonUtility.ToJson(gs); File.WriteAllText(path, json, System.Text.Encoding.UTF8); return true; } catch (System.Exception e) { Debug.LogError($"SettingsData.SaveToFile failed: {e.Message}"); return false; } } // Статическая реализация LoadOrCreate: пытается загрузить, иначе создаёт из встроенных дефолтов и сохраняет public static GameSettings LoadOrCreateFromFileStatic(string path) { var loaded = LoadFromFile(path); if (loaded != null) return loaded; var created = CreateGameSettingsFromDefaults(); SaveToFile(path, created); return created; } const string DefaultFileName = "settings.json"; public static string GetDefaultFilePath() { return Path.Combine(Application.persistentDataPath, DefaultFileName); } // Обертки: статические версии, использующие путь по умолчанию public static GameSettings LoadFromDefaultPath() { return LoadFromFile(GetDefaultFilePath()); } public static bool SaveToDefaultPath(GameSettings gs) { return SaveToFile(GetDefaultFilePath(), gs); } public static GameSettings LoadOrCreateFromFileDefault() { return LoadOrCreateFromFileStatic(GetDefaultFilePath()); } // Экземплярные обёртки (работают через этот ScriptableObject) public GameSettings TryLoadFromDefaultPath() { return TryLoadFromFile(GetDefaultFilePath()); } public bool TrySaveToDefaultPath(GameSettings gs) { return TrySaveToFile(GetDefaultFilePath(), gs); } public GameSettings LoadOrCreateFromDefaultPath() { return LoadOrCreateFromFile(GetDefaultFilePath()); } // Возвращает хеш дефолтов (чтобы не создавать GameSettings в менеджере) public int GetDefaultsHash() { return ComputeHash(GetDefaults()); } // Instance wrapper для сохранения GameSettings в путь по умолчанию public bool SaveGameSettings(GameSettings gs) { return TrySaveToDefaultPath(gs); } // Instance wrapper для загрузки GameSettings из пути по умолчанию public GameSettings LoadGameSettings() { return TryLoadFromDefaultPath(); } // Instance wrapper LoadOrCreate public GameSettings LoadOrCreateGameSettings() { return LoadOrCreateFromDefaultPath(); } }