diff --git a/Assets/Fonts/NEW/NexaRegular COOL.asset b/Assets/Fonts/NEW/NexaRegular COOL.asset index ddc825c..43d6970 100644 --- a/Assets/Fonts/NEW/NexaRegular COOL.asset +++ b/Assets/Fonts/NEW/NexaRegular COOL.asset @@ -11349,7 +11349,7 @@ Material: - _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767} - _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0} - _FaceColor: {r: 1, g: 1, b: 1, a: 1} - - _GlowColor: {r: 1, g: 0.528794, b: 0, a: 1} + - _GlowColor: {r: 0, g: 1, b: 0.87572384, a: 1} - _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767} - _OutlineColor: {r: 0.554717, g: 0.554717, b: 0.554717, a: 1} - _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/Scripts/Config.cs b/Assets/Scripts/Config.cs new file mode 100644 index 0000000..76cceb1 --- /dev/null +++ b/Assets/Scripts/Config.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using System.Text; + +public class Config +{ + [JsonProperty("serial")] + public string Serial { get; set; } = "<серийный номер не указан>"; + + [JsonProperty("light-version")] + public int LightVersion { get; set; } = 2; + + [JsonProperty("electronic-version")] + public int ElectronicVersion { get; set; } = 2; + + [JsonProperty("sensor-positive-value")] + public int SensorPositiveValue { get; set; } = 0; + + [JsonProperty("start-server")] + public bool StartServer { get; set; } = false; + + [JsonProperty("server-password")] + public string ServerPassword { get; set; } = "1234"; + + public void UpdateFromJson(string json) + { + JsonConvert.PopulateObject(json, this); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"serial: {Serial}"); + sb.AppendLine($"light-version: {LightVersion}"); + sb.AppendLine($"electronic-version: {ElectronicVersion}"); + sb.AppendLine($"sensor-positive-value: {SensorPositiveValue}"); + sb.AppendLine($"start-server: {StartServer}"); + sb.Append($"server-password: {ServerPassword}"); + + return sb.ToString(); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Config.cs.meta b/Assets/Scripts/Config.cs.meta new file mode 100644 index 0000000..f8b64e8 --- /dev/null +++ b/Assets/Scripts/Config.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 655ca697b0e20b54ca54bfe90132e1b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ConfigManager.cs b/Assets/Scripts/ConfigManager.cs new file mode 100644 index 0000000..832eda5 --- /dev/null +++ b/Assets/Scripts/ConfigManager.cs @@ -0,0 +1,47 @@ +using Newtonsoft.Json; +using System.IO; +using UnityEngine; + +public static class ConfigManager +{ + public static string configPath => Path.Combine(Application.persistentDataPath, "Config.rr"); + public static Config Config { get; private set; } + + public static void Initialize() + { + Config = LoadConfiguration(configPath); + } + + private static Config LoadConfiguration(string path) + { + try + { + if (File.Exists(path)) + { + string jsonContent = File.ReadAllText(path); + Config config = JsonConvert.DeserializeObject(jsonContent); + + if (config != null) + { + Debug.Log("Конфигурация успешно загружена"); + return config; + } + else + { + Debug.LogWarning("Файл конфигурации пуст, создаем новую конфигурацию"); + return new Config(); + } + } + else + { + Debug.LogWarning($"Файл конфигурации не найден по пути: {path}, создаем новую конфигурацию"); + return new Config(); + } + } + catch (System.Exception e) + { + Debug.LogError($"Ошибка при загрузке конфигурации: {e.Message}"); + return new Config(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/ConfigManager.cs.meta b/Assets/Scripts/ConfigManager.cs.meta new file mode 100644 index 0000000..752890d --- /dev/null +++ b/Assets/Scripts/ConfigManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb3e193cfb652b947ab69876176ee76f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ExternalFilesGetter.cs b/Assets/Scripts/ExternalFilesGetter.cs index cbacd75..d69d63b 100644 --- a/Assets/Scripts/ExternalFilesGetter.cs +++ b/Assets/Scripts/ExternalFilesGetter.cs @@ -4,197 +4,8 @@ using UnityEngine; public static class ExternalFilesGetter { - const string GAMEDATA_FOLDER = "C4"; - const string SERIAL_PATH = "serialdata.dat"; - const string OVERRIDES_FILE = "overrides/Light.conf"; - const string ELEKTRO_VERSION_FILE = "elektro_version.rr"; - const string SENSOR_VERSION_FILE = "HopperSensor.rr"; const string SETTINGS_PASSWORD = "SettingsPwd.rr"; - - - - - - public static string GetSerial() - { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string filePath = Path.Combine(docPath, GAMEDATA_FOLDER, SERIAL_PATH); - - try - { - // Проверяем существование файла - if (!File.Exists(filePath)) - { - Debug.LogWarning($"Файл serialdata.dat не найден по пути: {filePath}"); - return "<не указано>"; - } - - // Читаем весь текст из файла - string serialData = File.ReadAllText(filePath); - - // Убираем лишние пробелы и проверяем на пустоту - if (string.IsNullOrWhiteSpace(serialData)) - { - Debug.LogWarning("Файл serialdata.dat пуст"); - return "<не указано>"; - } - - return serialData.Trim(); - } - catch (Exception ex) - { - Debug.LogError($"Ошибка при чтении файла serialdata.dat: {ex.Message}"); - return "<не указано>"; - } - } - - public static string GetLightVersion() - { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string filePath = Path.Combine(docPath, GAMEDATA_FOLDER, OVERRIDES_FILE); - - try - { - // Проверяем существование файла - if (!File.Exists(filePath)) - { - Debug.LogWarning($"Файл не найден по пути: {filePath}"); - return ""; - } - - // Читаем весь текст из файла - string serialData = File.ReadAllText(filePath); - - // Убираем лишние пробелы и проверяем на пустоту - if (string.IsNullOrWhiteSpace(serialData)) - { - Debug.LogWarning("Файл пуст"); - return ""; - } - - return serialData.Trim(); - } - catch (Exception ex) - { - Debug.LogError($"Ошибка при чтении файла: {ex.Message}"); - return ""; - } - } - public static bool NeedToStartServer() - { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string filePath = Path.Combine(docPath, GAMEDATA_FOLDER, "serverOn.rr"); - - try - { - // Проверяем существование файла - if (!File.Exists(filePath)) return false; - - // Читаем содержимое файла - string content = File.ReadAllText(filePath).Trim(); - if (string.IsNullOrWhiteSpace(content)) return false; - - if(content == "1") - return true; - else - return false; - } - catch (Exception ex) - { - Debug.LogError($"Ошибка при чтении файла пароля: {ex.Message}"); - return false; - } - } - - - public static string GetElektroVersion() - { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string filePath = Path.Combine(docPath, GAMEDATA_FOLDER, ELEKTRO_VERSION_FILE); - - try - { - // Проверяем существование файла - if (!File.Exists(filePath)) - { - Debug.LogWarning($"Файл {ELEKTRO_VERSION_FILE} не найден по пути: {filePath}"); - return string.Empty; - } - - // Читаем содержимое файла - string versionData = File.ReadAllText(filePath).Trim(); - - // Убираем лишние пробелы и проверяем на пустоту - if (string.IsNullOrWhiteSpace(versionData)) - { - Debug.LogWarning($"Файл {ELEKTRO_VERSION_FILE} пуст"); - return string.Empty; - } - - // Проверяем содержимое файла - Debug.Log($"Считана версия подключения кнопок: {versionData}"); - return versionData; - } - catch (Exception ex) - { - Debug.LogError($"Ошибка при чтении файла {ELEKTRO_VERSION_FILE}: {ex.Message}"); - return string.Empty; - } - } - - - public static char GetSensorPositiveValue() - { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string filePath = Path.Combine(docPath, GAMEDATA_FOLDER, SENSOR_VERSION_FILE); - - char china_hopper_positive = '0'; //позитивное значение для китайских хопперов (Нормально разомкнутый (по умолчанию) - char ru_hopper_positive = '1'; //позитивное значение для русского хоппера (Нормально замкнутый) - - - try - { - // Проверяем существование файла - if (!File.Exists(filePath)) - { - Debug.LogWarning($"Файл {SENSOR_VERSION_FILE} не найден по пути: {filePath}"); - return china_hopper_positive; - } - - // Читаем содержимое файла - string versionData = File.ReadAllText(filePath).Trim(); - - // Убираем лишние пробелы и проверяем на пустоту - if (string.IsNullOrWhiteSpace(versionData)) - { - Debug.LogWarning($"Файл {SENSOR_VERSION_FILE} пуст"); - return china_hopper_positive; - } - - char result = china_hopper_positive; - switch (versionData) - { - case "1": - result = china_hopper_positive; - break; - case "2": - result = ru_hopper_positive; - break; - default: - result = china_hopper_positive; - break; - } - - return result; - } - catch (Exception ex) - { - Debug.LogError($"Ошибка при чтении файла {SENSOR_VERSION_FILE}: {ex.Message}"); - return china_hopper_positive; - } - } - public static string GetSettingsPassword() { string filePath = Path.Combine(Application.persistentDataPath, SETTINGS_PASSWORD); @@ -242,6 +53,5 @@ public static class ExternalFilesGetter throw; } } - } diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 617be90..7854768 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -454,6 +454,7 @@ public class GameManager : MonoBehaviour chipTransforms = new Transform[Rows, Cols]; } + ConfigManager.Initialize(); UnityMainThreadDispatcher.Initialize(); InitializePrefs(); @@ -561,7 +562,7 @@ public class GameManager : MonoBehaviour private static void InitializePrefs() { - PlayerPrefs.SetString("Serial", ExternalFilesGetter.GetSerial()); + PlayerPrefs.SetString("Serial", ConfigManager.Config.Serial); if (!PlayerPrefs.HasKey("Number")) PlayerPrefs.SetString("Number", "70000000000"); if (!PlayerPrefs.HasKey("ValutaPerImpulse")) PlayerPrefs.SetInt("ValutaPerImpulse", 10); diff --git a/Assets/Scripts/Inputs/COMinput.cs b/Assets/Scripts/Inputs/COMinput.cs index bf5d1e3..4b7c67e 100644 --- a/Assets/Scripts/Inputs/COMinput.cs +++ b/Assets/Scripts/Inputs/COMinput.cs @@ -55,12 +55,12 @@ public class COMinput : InputSource /// private void LoadPinMappingConfiguration() { - string elektroVersion = ExternalFilesGetter.GetElektroVersion(); + int elektroVersion = ConfigManager.Config.ElectronicVersion; Debug.Log($"Определена версия электроники: {elektroVersion}"); // Создаем маппинг в зависимости от версии - if (elektroVersion == "1") + if (elektroVersion == 1) { // Версия 1 (старая распиновка) pinMappings[ButtonPinMapping.up1] = 0; @@ -331,7 +331,9 @@ public class COMinput : InputSource //Проверка прошел ли приз через сенсор int prizeSensorPin = GetPhysicalPin(ButtonPinMapping.hasPrize); - char sensorPositive = ExternalFilesGetter.GetSensorPositiveValue(); + + char sensorPositive = ConfigManager.Config.SensorPositiveValue.ToString()[0]; + if (prizeSensorPin < input.Length && input[prizeSensorPin] == sensorPositive) { PlayerPrefs.SetInt("PrizeGivenBuffer", 1); diff --git a/Assets/Scripts/LightUtility.cs b/Assets/Scripts/LightUtility.cs index ace4d0a..c1091fb 100644 --- a/Assets/Scripts/LightUtility.cs +++ b/Assets/Scripts/LightUtility.cs @@ -90,10 +90,8 @@ public static class LightUtility string lightsingal; //определить версию - string version = ExternalFilesGetter.GetLightVersion(); - - - if (version == "1") + int version = ConfigManager.Config.LightVersion; + if (version == 1) { //Debug.Log("1 версия подсветки"); //1 версия diff --git a/Assets/Scripts/Server/AuthManager.cs b/Assets/Scripts/Server/AuthManager.cs index 8b0305c..c8e03ec 100644 --- a/Assets/Scripts/Server/AuthManager.cs +++ b/Assets/Scripts/Server/AuthManager.cs @@ -11,29 +11,6 @@ public static class AuthManager private const string TokenSeparator = "."; private const string AppSalt = "FISHKA_WEB_ADMIN_V1"; // поменяй на своё - // Берем пароль из файла (если есть), иначе fallback из инспектора - public static string LoadPasswordOrFallback(string fallback, string fileName) - { - try - { - string path = Path.Combine(Application.persistentDataPath, fileName); - if (File.Exists(path)) - { - var s = File.ReadAllText(path, Encoding.UTF8).Trim(); - if (!string.IsNullOrEmpty(s)) - { - Debug.Log($"Password loaded from file. {s}"); - return s; - } - } - } - catch (Exception e) - { - Debug.LogWarning($"Password file read failed: {e.Message}"); - } - return fallback ?? ""; - } - public static bool VerifyPassword(string entered, string actual) { if (entered == null) entered = ""; diff --git a/Assets/Scripts/Server/WebServer.cs b/Assets/Scripts/Server/WebServer.cs index c9f882d..325ad1d 100644 --- a/Assets/Scripts/Server/WebServer.cs +++ b/Assets/Scripts/Server/WebServer.cs @@ -23,7 +23,6 @@ public class WebServer : MonoBehaviour [Header("Auth")] [SerializeField] private string adminPasswordFallback = "1234"; // если файла нет - [SerializeField] private string passwordFileName = "admin_password.txt"; // лежит в persistentDataPath private string AdminPassword; @@ -33,13 +32,13 @@ public class WebServer : MonoBehaviour async void Start() { - if (ExternalFilesGetter.NeedToStartServer() == false) + if (ConfigManager.Config.StartServer == false) { //Debug.Log("Web сервер не запущен (по настройке)"); return; } - AdminPassword = AuthManager.LoadPasswordOrFallback(adminPasswordFallback, passwordFileName); + AdminPassword = ConfigManager.Config.ServerPassword; LoadCss(); settingActions = GameManager.instance.AdminPanel.GetComponent().settingActions; @@ -509,6 +508,7 @@ public class WebServer : MonoBehaviour void OnDestroy() { + if (!isRunning) return; isRunning = false; listener?.Stop(); listener?.Close(); diff --git a/Tools/ConfigappV2/utils/encryption.py b/Tools/ConfigappV2/utils/encryption.py index 407a3e0..9ac6484 100644 --- a/Tools/ConfigappV2/utils/encryption.py +++ b/Tools/ConfigappV2/utils/encryption.py @@ -54,47 +54,15 @@ class ConfigManager: for callback in self._observers: callback() - def _derive_key(self) -> bytes: - """Создает ключ Fernet из строки""" - # Соль фиксированная для обратной совместимости - salt = b'fishka_salt_1234' - kdf = PBKDF2HMAC( - algorithm=hashes.SHA256(), - length=32, - salt=salt, - iterations=100000, - ) - key = base64.urlsafe_b64encode(kdf.derive(self.key_string.encode())) - return key - - def encrypt_data(self, data: Dict[str, Any]) -> bytes: - """Шифрует словарь в строку JSON и затем шифрует""" - json_str = json.dumps(data, ensure_ascii=False, indent=2) - fernet = Fernet(self._derive_key()) - encrypted = fernet.encrypt(json_str.encode('utf-8')) - return encrypted - - def decrypt_data(self, encrypted_data: bytes) -> Dict[str, Any]: - """Расшифровывает данные""" - try: - fernet = Fernet(self._derive_key()) - decrypted = fernet.decrypt(encrypted_data) - return json.loads(decrypted.decode('utf-8')) - except Exception as e: - print(f"Ошибка расшифровки: {e}") - return {} - def save_config(self, data: Dict[str, Any]) -> bool: """Сохраняет конфиг в файл в AppData/LocalLow""" - try: - encrypted = self.encrypt_data(data) - + try: # Убеждаемся, что директория существует os.makedirs(self.config_dir, exist_ok=True) # Сохраняем файл - with open(self.config_path, 'wb') as f: - f.write(encrypted) + with open(self.config_path, 'w', encoding="utf-8") as f: + json.dump(data, f, indent=2) print(f"Конфиг сохранен: {self.config_path}") self.current_config = data @@ -111,10 +79,9 @@ class ConfigManager: return {} try: - with open(self.config_path, 'rb') as f: - encrypted = f.read() + with open(self.config_path, 'r') as f: + config = json.load(f) - config = self.decrypt_data(encrypted) print(f"Конфиг загружен: {self.config_path}") return config except Exception as e: