From e215dce46ede45bee40e7ce2efe1e18232f33313 Mon Sep 17 00:00:00 2001 From: _sega Date: Tue, 24 Feb 2026 16:46:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=9F=D0=B5=D1=80=D0=9A=D0=BE=D0=BDV2.=20=D0=A3?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=BB=20=D0=B1=D0=B0=D0=B3=20=D1=81=20=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=8E=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Fonts/NEW/NexaRegular COOL.asset | 2 +- Assets/Scripts/CharacterSettingPanel.cs | 4 +- Assets/Scripts/CoinCounter.cs | 2 +- Assets/Scripts/GameManager.cs | 4 +- Assets/Scripts/Inputs/COMinput.cs | 2 + Assets/Scripts/Inputs/ComSystem/ComWrapper.cs | 145 ++++++++++++++++-- .../ComSystem/PeripheralControllerV2.cs | 11 +- Assets/Scripts/Inputs/In.cs | 14 +- Assets/Scripts/Logger.cs | 2 +- .../Scripts/DualAvatarController.cs | 4 +- Assets/Scripts/PrizeSystem/PrizeSystem.cs | 22 ++- Assets/Scripts/Settings/SettingsContainer.cs | 2 +- 12 files changed, 179 insertions(+), 35 deletions(-) diff --git a/Assets/Fonts/NEW/NexaRegular COOL.asset b/Assets/Fonts/NEW/NexaRegular COOL.asset index 1f31f70..725bf06 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: 0.63619995, g: 0, b: 1, a: 1} + - _GlowColor: {r: 0, g: 1, b: 0.7143903, 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/CharacterSettingPanel.cs b/Assets/Scripts/CharacterSettingPanel.cs index 20a89e0..77c5b8e 100644 --- a/Assets/Scripts/CharacterSettingPanel.cs +++ b/Assets/Scripts/CharacterSettingPanel.cs @@ -162,7 +162,7 @@ public class CharacterSettingPanel : MonoBehaviour { return 0; } - if (prizeType == PrizeType.Hopper) + if (prizeType == PrizeType.Hopper || prizeType == PrizeType.Hopper2) { return Mathf.Clamp(amount, 1, 5); } @@ -239,7 +239,6 @@ public class CharacterSettingPanel : MonoBehaviour private void SaveAndClose() { - Debug.Log("Сохранение конфига персонажей"); PrizeSerializer.SetPrizes(prizes); CharacterController.I.RefreshPrizes(); timeRest = timeToConfirm; @@ -284,5 +283,4 @@ public class CharacterSettingPanel : MonoBehaviour yield return null; } } - } diff --git a/Assets/Scripts/CoinCounter.cs b/Assets/Scripts/CoinCounter.cs index 5246ae7..a966374 100644 --- a/Assets/Scripts/CoinCounter.cs +++ b/Assets/Scripts/CoinCounter.cs @@ -36,7 +36,7 @@ public class CoinCounter : MonoBehaviour public void SetRevengePriceVisibility(bool visibility) { - revengeSignGo.SetActive(visibility); + revengeSignGo?.SetActive(visibility); int priceRevenge = PlayerPrefs.GetInt("PriceRevenge", 10); int pricePve = PlayerPrefs.GetInt("PricePVE", 10); string valutaName = PlayerPrefs.GetString("ValutaName", "руб."); diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 13536b1..ee4b7fc 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -452,7 +452,9 @@ public class GameManager : MonoBehaviour SettingsManager.Initialize(); GetComponent().Initialize(); - ComWrapper.Initialize(); + //Тестируем пока что. Не прод + ComWrapper.Initialize(ComNativeWrapper.ListPorts(), 2); + SingleWallet.Initialize(); diff --git a/Assets/Scripts/Inputs/COMinput.cs b/Assets/Scripts/Inputs/COMinput.cs index d576874..a00b506 100644 --- a/Assets/Scripts/Inputs/COMinput.cs +++ b/Assets/Scripts/Inputs/COMinput.cs @@ -28,6 +28,7 @@ public class COMinput : InputSource private int currentPlayer => gm.currentPlayer == CellState.Player1 ? 1 : 2;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ. private GameManager gm;//я получаю кто сейчас ходит через этого менеджера. Если у вас другое, допишите. + public override bool Initialize() { try @@ -304,6 +305,7 @@ public class COMinput : InputSource //DebugWindow.Message($"В инпут пришло: {input}"); // Будем принимать в нативном формате by Pasha. 0 - нажато 1 - не нажато (чтобы преобразовывать циклом) // В параметр приходит строка вида "1111011111011111" + input = input.Substring(0, PIN_COUNT); for (int i = 0; i < input.Length; i++) { // Получаем новое состояние пина diff --git a/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs b/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs index e913cd6..bb56aef 100644 --- a/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs +++ b/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs @@ -4,6 +4,8 @@ using UnityEngine; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEditorInternal.VR; /// @@ -25,16 +27,22 @@ public static class ComWrapper private static CancellationTokenSource _readerCts; private static int h; + public static int BoardVersion { get; private set; } private static ILogger logger; + private static string[] AvailablePorts; private static int _lastInputTick = 0; private const int INPUT_IDLE_BEFORE_PING_MS = 60_000;//1 минута - public static void Initialize()//Добавить логгер в конструктор + + public static void Initialize(string[] availablePorts, int boardVersion)//Добавить логгер в конструктор { + BoardVersion = boardVersion; + AvailablePorts = availablePorts; + if (_lifetimeCts != null) return; - OpenPort(); + OpenPort(AvailablePorts); if (h <= 0) { Log("Порт не открылся при инициализации"); @@ -44,7 +52,7 @@ public static class ComWrapper UnityMainThreadDispatcher.Initialize(); _lifetimeCts = new CancellationTokenSource(); - + StartReaderThread(); _ = SetupBoardAsync(_lifetimeCts.Token); } @@ -92,7 +100,7 @@ public static class ComWrapper if (read > 0) { var line = Encoding.UTF8.GetString(buffer, 0, read).Trim(); - EnqueueLine(line); + EnqueueLine(line); } } }); @@ -103,14 +111,14 @@ public static class ComWrapper private static void StopReaderThread() { - if(_readerCts != null) + if (_readerCts != null) { _readerCts.Cancel(); _readerCts.Dispose(); _readerCts = null; } - if(_readerThread != null) + if (_readerThread != null) { _readerThread.Join(200); _readerThread = null; @@ -127,11 +135,19 @@ public static class ComWrapper Log($"COM. h={h}: {line}"); if (line == "COIN") + { PaymentReceived?.Invoke(); + Send("10"); + + } else if (line.StartsWith("INPUT")) { Volatile.Write(ref _lastInputTick, Environment.TickCount); - InputRecieved?.Invoke(line.Substring(5)); + + string rawInputString = line.Substring(5); + string inputString = BoardVersion == 2 ? DecimalToBinary(rawInputString) : rawInputString; + + InputRecieved?.Invoke(inputString); } } @@ -168,6 +184,40 @@ public static class ComWrapper return tcs.Task; } + /// + /// Очищает буфер порта от накопившихся старых данных + /// + private static void FlushPortBuffer() + { + try + { + // Проверяем валидность handle + if (h <= 0) + { + return; + } + + // Используем локальный буфер + byte[] localBuf = new byte[1024]; + + int flushedCount = 0; + + // Читаем все накопившиеся данные из порта + int read; + while ((read = ComNativeWrapper.Serial_ReadLineUTF8_bytes(h, localBuf, localBuf.Length)) > 0) + { + flushedCount++; + if (flushedCount > 100) break; // Защита от бесконечного цикла + } + + Log($"Очищено: {flushedCount} сообщений"); + } + catch (Exception e) + { + Log($"FlushPortBuffer exception: {e.Message}"); + } + } + static Task WaitForPrefixAsync(string prefix, int timeoutMs, CancellationToken ct) => WaitForAsync(s => s.StartsWith(prefix, StringComparison.Ordinal), timeoutMs, ct); @@ -205,7 +255,12 @@ public static class ComWrapper private static async Task SetupBoardAsync(CancellationToken ct) { - bool auth = await BoardAuthAsync(ct); + bool auth; + if (BoardVersion == 1) + auth = await BoardAuthAsync(ct); + else + auth = true; + if (!auth) { Log("Авторизация на плате не пройдена."); @@ -216,14 +271,15 @@ public static class ComWrapper _ = StartKeepAliveProcessAsync(ct); } - private static void OpenPort() + private static async Task OpenPort(string[] availablePorts) { Log("Инициализация порта"); - var ports = ComNativeWrapper.ListPorts(); + var ports = availablePorts; if (ports.Length == 0) { Log("Нет портов, завершаю"); return; } string port = ports[^1]; + ComNativeWrapper.Serial_CloseAll(); Log("Открываю порт: " + port); h = ComNativeWrapper.Serial_Open(port, 115200, 8, 0, 1, 4, 10); @@ -238,9 +294,70 @@ public static class ComWrapper else { Log($"Открыл порт: {port}"); + FlushPortBuffer(); + + } + + WaitAllCoins(); + } + + static void WaitAllCoins() + { + int count = 0; + int maxCount = 100; + long timeout = 3000; + + byte[] bytes = new byte[1024]; + long startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + long lastCoinTime = startTime; + while (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - lastCoinTime < 250) + { + int w = ComNativeWrapper.Serial_ReadLineUTF8_bytes(h, bytes, bytes.Length); + if (w <= 0) continue; + if( Encoding.UTF8.GetString(bytes, 0, w) == "COIN") + { + lastCoinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + Send("10"); + count++; + } + if (count >= maxCount) break; + if(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startTime >= timeout) break; + } + Debug.Log("count coins " + count); + } + + /// + /// Преобразует строку с десятичным числом в двоичное представление. + /// Младшие биты слева, старшие справа (перевёрнутый порядок для соответствия индексам пинов). + /// + /// Строка с десятичным числом + /// Строка с двоичным представлением + private static string DecimalToBinary(string decimalString) + { + try + { + if (long.TryParse(decimalString, out long decimalValue)) + { + // Стандартное преобразование: старшие биты слева + string binary = Convert.ToString(decimalValue, 2); + + // Переворачиваем строку: младшие биты слева, старшие справа + char[] chars = binary.ToCharArray(); + Array.Reverse(chars); + return new string(chars); + } + + Debug.Log($"Не удалось распарсить значение INPUT: {decimalString}"); + return "11111111111111111111111111"; // 26 единиц по умолчанию + } + catch (Exception e) + { + Debug.Log($"Ошибка преобразования в двоичную систему: {e.Message}"); + return "11111111111111111111111111"; // 26 единиц по умолчанию } } + private static async Task BoardAuthAsync(CancellationToken ct) { //Проверяем зашифрована или нет @@ -254,7 +371,7 @@ public static class ComWrapper { //Не пришел инпут Log("Шифрованная плата"); - } + } //Запрашиваем шифрованную строку string encLine; @@ -363,7 +480,7 @@ public static class ComWrapper try { Send(REQUEST_INPUT_COMMAND); - await WaitForPrefixAsync("INPUT", 1000, ct); + await WaitForPrefixAsync("INPUT", 1000, ct); return true; } catch @@ -379,7 +496,7 @@ public static class ComWrapper CancelAllWaiters(); ClosePort(); - OpenPort(); + OpenPort(AvailablePorts); if (h <= 0) { Log($"Ошибка при переподключении."); @@ -389,7 +506,7 @@ public static class ComWrapper StartReaderThread(); var auth = await BoardAuthAsync(ct); - if (!auth) + if (!auth) UnityMainThreadDispatcher.Instance.Enqueue(() => (new GameObject()).AddComponent(typeof(VfxPrefab))); } diff --git a/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs index 95cb022..386c6aa 100644 --- a/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs +++ b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs @@ -15,6 +15,15 @@ public class PeripheralControllerV2 : ComDevice private const string REQUEST_ENCRYPTED_COMMAND = "666"; private const string REQUEST_CONFIRMATION_COMMAND = "777"; + private static readonly byte[] AesEncryptedKey = + { + 0x69, 0x40, 0xC7, 0x0E, 0xF2, 0xC7, 0x45, 0x70, + 0x72, 0xCD, 0x28, 0x58, 0x99, 0x8F, 0x73, 0xA8, + 0x5F, 0x5F, 0xED, 0xB4, 0xC1, 0x62, 0xB4, 0x24, + 0xAC, 0xD7, 0xA3, 0xD6, 0xD8, 0x0B, 0x50, 0x37 + }; + + private CancellationTokenSource _lifetimeCts; private Thread _readerThread; private CancellationTokenSource _readerCts; @@ -47,7 +56,7 @@ public class PeripheralControllerV2 : ComDevice if (h <= 0) return; try { - int w = ComNativeWrapper.Serial_WriteStringUTF8(h, message, 1); //w-количество записаных символов в порт. можно обработать + int w = ComNativeWrapper.Serial_WriteStringUTF8(h, message, 1); } catch { logger?.Log($"Ошибка отправки строкового сигнала. {message}"); } } diff --git a/Assets/Scripts/Inputs/In.cs b/Assets/Scripts/Inputs/In.cs index 68820c9..5413600 100644 --- a/Assets/Scripts/Inputs/In.cs +++ b/Assets/Scripts/Inputs/In.cs @@ -39,13 +39,15 @@ public class In : MonoBehaviour _ => throw new System.NotImplementedException() };*/ -#if UNITY_EDITOR - source = new KeyboardInput(); -#else - source = new COMinput(); -#endif - + //ТЕСТЫ +//#if UNITY_EDITOR +// source = new KeyboardInput(); +//#else +// source = new COMinput(); +//#endif + + source = new COMinput(); var success = source.Initialize(); diff --git a/Assets/Scripts/Logger.cs b/Assets/Scripts/Logger.cs index 3bd128a..7033b14 100644 --- a/Assets/Scripts/Logger.cs +++ b/Assets/Scripts/Logger.cs @@ -44,7 +44,7 @@ public class Logger : MonoBehaviour writer.WriteLine(startMessage); writer.Flush(); - Debug.Log($"Логгер инициализирован. Файл: {logFilePath}"); + //Debug.Log($"Логгер инициализирован. Файл: {logFilePath}"); } catch (Exception e) { diff --git a/Assets/Scripts/PVP Characters/Scripts/DualAvatarController.cs b/Assets/Scripts/PVP Characters/Scripts/DualAvatarController.cs index 0b8c22b..e92e147 100644 --- a/Assets/Scripts/PVP Characters/Scripts/DualAvatarController.cs +++ b/Assets/Scripts/PVP Characters/Scripts/DualAvatarController.cs @@ -69,8 +69,8 @@ public class DualAvatarController : MonoBehaviour public void HideCharacters() { StopAllCoroutines(); - StartCoroutine(MoveLocal(avatars[PLAYER1], GetHiddenPosition(PLAYER1), CharacterMovementSpeed, OnComplete: () => print("hided"))); - StartCoroutine(MoveLocal(avatars[PLAYER2], GetHiddenPosition(PLAYER2), CharacterMovementSpeed, OnComplete: () => print("hided"))); + StartCoroutine(MoveLocal(avatars[PLAYER1], GetHiddenPosition(PLAYER1), CharacterMovementSpeed, OnComplete: () => { })); + StartCoroutine(MoveLocal(avatars[PLAYER2], GetHiddenPosition(PLAYER2), CharacterMovementSpeed, OnComplete: () => { })); } Avatar CreateAvatar(GameObject prefab, Transform parent, CellState team) diff --git a/Assets/Scripts/PrizeSystem/PrizeSystem.cs b/Assets/Scripts/PrizeSystem/PrizeSystem.cs index aef4cf6..d0e84e4 100644 --- a/Assets/Scripts/PrizeSystem/PrizeSystem.cs +++ b/Assets/Scripts/PrizeSystem/PrizeSystem.cs @@ -81,8 +81,16 @@ public class PrizeSystem : MonoBehaviour float timeout = 10; - Debug.Log("Начинаю выдачу 303"); - ComWrapper.Send("303");//включаем мотор + + string enableMotorComand = ComWrapper.BoardVersion switch + { + 1 => "303", + 2 => "301", + _ => "303" + }; + + Debug.Log($"Включаю мотор хоппера: {enableMotorComand}"); + ComWrapper.Send(enableMotorComand);//включаем мотор float startTime = Time.time; bool success = false; @@ -101,8 +109,14 @@ public class PrizeSystem : MonoBehaviour } //Выключаем мотор - Debug.Log("Выключаю мотор"); - ComWrapper.Send("302"); + string disableMotorComand = ComWrapper.BoardVersion switch + { + 1 => "302", + 2 => "300", + _ => "302" + }; + Debug.Log($"Выключаю мотор: {disableMotorComand}"); + ComWrapper.Send(disableMotorComand); Debug.Log("Закончил. Успех: " + success); prizing = false; diff --git a/Assets/Scripts/Settings/SettingsContainer.cs b/Assets/Scripts/Settings/SettingsContainer.cs index 3c29efb..ac59e29 100644 --- a/Assets/Scripts/Settings/SettingsContainer.cs +++ b/Assets/Scripts/Settings/SettingsContainer.cs @@ -4,7 +4,7 @@ using System.Text; using UnityEngine; [System.Serializable] -public class SettingsContainer : MonoBehaviour +public class SettingsContainer { public List Settings { get; private set; }