diff --git a/Assets/Fonts/NEW/NexaRegular COOL.asset b/Assets/Fonts/NEW/NexaRegular COOL.asset index 956f73c..1f31f70 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.91854715, g: 0, b: 1, a: 1} + - _GlowColor: {r: 0.63619995, g: 0, b: 1, 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/Materials/CharacterTrailMat.mat b/Assets/Materials/CharacterTrailMat.mat deleted file mode 100644 index 9779c37..0000000 --- a/Assets/Materials/CharacterTrailMat.mat +++ /dev/null @@ -1,112 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: CharacterTrailMat - m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: - - _ALPHABLEND_ON - - _EMISSION - m_LightmapFlags: 0 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _AlphaTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 2800000, guid: f4792ca58fafabe438e2126cac5b6651, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - PixelSnap: 0 - - _BlendOp: 0 - - _BumpScale: 1 - - _CameraFadingEnabled: 0 - - _CameraFarFadeDistance: 2 - - _CameraNearFadeDistance: 1 - - _ColorMode: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailNormalMapScale: 1 - - _DistortionBlend: 0.5 - - _DistortionEnabled: 0 - - _DistortionStrength: 1 - - _DistortionStrengthScaled: 0 - - _DstBlend: 10 - - _EmissionEnabled: 0 - - _EnableExternalAlpha: 0 - - _FlipbookMode: 0 - - _GlossMapScale: 1 - - _Glossiness: 0.5 - - _GlossyReflections: 1 - - _LightingEnabled: 0 - - _Metallic: 0 - - _Mode: 2 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _SmoothnessTextureChannel: 0 - - _SoftParticlesEnabled: 0 - - _SoftParticlesFarFadeDistance: 1 - - _SoftParticlesNearFadeDistance: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 5 - - _UVSec: 0 - - _ZWrite: 0 - m_Colors: - - _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0} - - _Color: {r: 1, g: 1, b: 1, a: 1} - - _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _Flip: {r: 1, g: 1, b: 1, a: 1} - - _RendererColor: {r: 1, g: 1, b: 1, a: 1} - - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/CharacterTrailMat.mat.meta b/Assets/Materials/CharacterTrailMat.mat.meta deleted file mode 100644 index 24c017e..0000000 --- a/Assets/Materials/CharacterTrailMat.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e5e12d87377e2284887adbcfc4fc356e -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Coins.mat b/Assets/Materials/Coins.mat deleted file mode 100644 index 923bcf6..0000000 --- a/Assets/Materials/Coins.mat +++ /dev/null @@ -1,111 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Coins - m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: - - _ALPHATEST_ON - m_LightmapFlags: 0 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _AlphaTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 2800000, guid: face08d206a2bea44b451368a18b1752, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - PixelSnap: 0 - - _BlendOp: 0 - - _BumpScale: 1 - - _CameraFadingEnabled: 0 - - _CameraFarFadeDistance: 2 - - _CameraNearFadeDistance: 1 - - _ColorMode: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailNormalMapScale: 1 - - _DistortionBlend: 0.5 - - _DistortionEnabled: 0 - - _DistortionStrength: 1 - - _DistortionStrengthScaled: 0 - - _DstBlend: 0 - - _EmissionEnabled: 0 - - _EnableExternalAlpha: 0 - - _FlipbookMode: 0 - - _GlossMapScale: 1 - - _Glossiness: 0 - - _GlossyReflections: 1 - - _LightingEnabled: 0 - - _Metallic: 0 - - _Mode: 1 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _SmoothnessTextureChannel: 0 - - _SoftParticlesEnabled: 0 - - _SoftParticlesFarFadeDistance: 1 - - _SoftParticlesNearFadeDistance: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _UVSec: 0 - - _ZWrite: 1 - m_Colors: - - _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0} - - _Color: {r: 1, g: 1, b: 1, a: 1} - - _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _Flip: {r: 1, g: 1, b: 1, a: 1} - - _RendererColor: {r: 1, g: 1, b: 1, a: 1} - - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Coins.mat.meta b/Assets/Materials/Coins.mat.meta deleted file mode 100644 index 3ec4ca9..0000000 --- a/Assets/Materials/Coins.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0b3c4a2ce664cbe47bcdbe3058e5de34 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Materials/Softness.mat b/Assets/Materials/Softness.mat deleted file mode 100644 index 5b2e1eb..0000000 --- a/Assets/Materials/Softness.mat +++ /dev/null @@ -1,85 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Softness - m_Shader: {fileID: 202, guid: 0000000000000000f000000000000000, type: 0} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _BumpScale: 1 - - _Cutoff: 0.5 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _GlossMapScale: 1 - - _Glossiness: 0.5 - - _GlossyReflections: 1 - - _InvFade: 0.01 - - _Metallic: 0 - - _Mode: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _UVSec: 0 - - _ZWrite: 1 - m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _TintColor: {r: 1, g: 1, b: 1, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Materials/Softness.mat.meta b/Assets/Materials/Softness.mat.meta deleted file mode 100644 index a058e2b..0000000 --- a/Assets/Materials/Softness.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 99f96c9ac3c491643b9ecda7b40658cd -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Prefabs/TrailMaterial.mat b/Assets/Materials/TrailMaterial.mat similarity index 100% rename from Assets/Prefabs/TrailMaterial.mat rename to Assets/Materials/TrailMaterial.mat diff --git a/Assets/Prefabs/TrailMaterial.mat.meta b/Assets/Materials/TrailMaterial.mat.meta similarity index 100% rename from Assets/Prefabs/TrailMaterial.mat.meta rename to Assets/Materials/TrailMaterial.mat.meta diff --git a/Assets/Scripts/Inputs/ComSystem/ComDevice.cs b/Assets/Scripts/Inputs/ComSystem/ComDevice.cs new file mode 100644 index 0000000..dc9dac8 --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/ComDevice.cs @@ -0,0 +1,13 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public abstract class ComDevice +{ + protected int h; + public ComDevice(int handleId) + { + h = handleId; + } + +} diff --git a/Assets/Scripts/Inputs/ComSystem/ComDevice.cs.meta b/Assets/Scripts/Inputs/ComSystem/ComDevice.cs.meta new file mode 100644 index 0000000..a9c9103 --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/ComDevice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04785a4d9ec0ed34eb40efc86f4ffcd6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Inputs/ComSystem/ComHub.cs b/Assets/Scripts/Inputs/ComSystem/ComHub.cs new file mode 100644 index 0000000..f10b7fc --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/ComHub.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public static class ComHub +{ + public static event Action InputRecieved; + public static event Action PaymentRecieved; + + + + public static string[] GetPortNames() + { + return null; + } + + public static int OpenPort(string portName) + { + + return 0; + } + + public static string GetRole(int handle) + { + + return string.Empty; + } + + public static ComDevice CreateDevice(int handle, ComDeviceType deviceType) + { + return null; + } +} + +public enum ComDeviceType +{ + PeripheralController, + PrizeStand +} diff --git a/Assets/Scripts/Inputs/ComSystem/ComHub.cs.meta b/Assets/Scripts/Inputs/ComSystem/ComHub.cs.meta new file mode 100644 index 0000000..9cfbb65 --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/ComHub.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5b90abed5b0bb848a505445ba94f03e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs b/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs index 29ca0e8..e913cd6 100644 --- a/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs +++ b/Assets/Scripts/Inputs/ComSystem/ComWrapper.cs @@ -216,9 +216,6 @@ public static class ComWrapper _ = StartKeepAliveProcessAsync(ct); } - - - private static void OpenPort() { Log("Инициализация порта"); @@ -257,7 +254,7 @@ public static class ComWrapper { //Не пришел инпут Log("Шифрованная плата"); - } + } //Запрашиваем шифрованную строку string encLine; diff --git a/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs new file mode 100644 index 0000000..95cb022 --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs @@ -0,0 +1,401 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using UnityEngine; + +public class PeripheralControllerV2 : ComDevice +{ + public event Action PaymentReceived; + public event Action InputRecieved; + + private const string REQUEST_INPUT_COMMAND = "91"; + private const string REQUEST_ENCRYPTED_COMMAND = "666"; + private const string REQUEST_CONFIRMATION_COMMAND = "777"; + + private CancellationTokenSource _lifetimeCts; + private Thread _readerThread; + private CancellationTokenSource _readerCts; + + //private int h; + private ILogger logger; + + private int _lastInputTick = 0; + private const int INPUT_IDLE_BEFORE_PING_MS = 60_000;//1 минута + + public PeripheralControllerV2(int handleId) : base(handleId) + { + if (_lifetimeCts != null) return; + OpenPort(); + if (h <= 0) + { + Log("Порт не открылся при инициализации"); + return; + } + + UnityMainThreadDispatcher.Initialize(); + _lifetimeCts = new CancellationTokenSource(); + + StartReaderThread(); + _ = SetupBoardAsync(_lifetimeCts.Token); + } + + public void Send(string message) + { + if (h <= 0) return; + try + { + int w = ComNativeWrapper.Serial_WriteStringUTF8(h, message, 1); //w-количество записаных символов в порт. можно обработать + } + catch { logger?.Log($"Ошибка отправки строкового сигнала. {message}"); } + } + + private void StartReaderThread() + { + StopReaderThread(); + + _readerCts = new CancellationTokenSource(); + var ct = _readerCts.Token; + + _readerThread = new Thread(() => + { + byte[] buffer = new byte[1024]; + + + while (!ct.IsCancellationRequested) + { + if (h <= 0) { Thread.Sleep(20); continue; } + int read = 0; + try + { + //блок до таймаута чтения + read = ComNativeWrapper.Serial_ReadLineUTF8_bytes(h, buffer, buffer.Length); + } + catch (Exception ex) + { + Log("Com reader exception: " + ex.Message); + Thread.Sleep(50);// пауза чтобы не уйти в спин при ошибке + continue; + } + + if (ct.IsCancellationRequested) break; + + if (read > 0) + { + var line = Encoding.UTF8.GetString(buffer, 0, read).Trim(); + EnqueueLine(line); + } + } + }); + + _readerThread.IsBackground = true; + _readerThread.Start(); + } + + private void StopReaderThread() + { + if (_readerCts != null) + { + _readerCts.Cancel(); + _readerCts.Dispose(); + _readerCts = null; + } + + if (_readerThread != null) + { + _readerThread.Join(200); + _readerThread = null; + } + } + + void EnqueueLine(string line) + { + UnityMainThreadDispatcher.Instance.Enqueue(() => OnLine(line)); + } + + private void ProcessComInput(string line) + { + Log($"COM. h={h}: {line}"); + + if (line == "COIN") + PaymentReceived?.Invoke(); + else if (line.StartsWith("INPUT")) + { + Volatile.Write(ref _lastInputTick, Environment.TickCount); + InputRecieved?.Invoke(line.Substring(5)); + } + } + + static readonly object _waitLock = new(); + static readonly List _waiters = new(); + sealed class Waiter + { + public Func Match; + public TaskCompletionSource Tcs; + } + static Task WaitForAsync(Func match, int timeoutMs, CancellationToken ct) + { + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var w = new Waiter { Match = match, Tcs = tcs }; + + lock (_waitLock) _waiters.Add(w); + + //отмена + if (ct.CanBeCanceled) + { + ct.Register(() => + { + lock (_waitLock) _waiters.Remove(w); + tcs.TrySetCanceled(ct); + }); + } + + _ = Task.Delay(timeoutMs, CancellationToken.None).ContinueWith(_ => + { + lock (_waitLock) _waiters.Remove(w); + tcs.TrySetException(new TimeoutException($"Timeout waiting for line")); + }); + + return tcs.Task; + } + + static Task WaitForPrefixAsync(string prefix, int timeoutMs, CancellationToken ct) + => WaitForAsync(s => s.StartsWith(prefix, StringComparison.Ordinal), timeoutMs, ct); + static Task WaitForContainsAsync(string prefix, int timeoutMs, CancellationToken ct) + => WaitForAsync(s => s.IndexOf(prefix, StringComparison.Ordinal) >= 0, timeoutMs, ct); + + private void OnLine(string line) + { + if (string.IsNullOrEmpty(line)) + return; + + //1. обычная обработка + ProcessComInput(line); + + //2. Разубудить ожидающих + List toFire = null; + + lock (_waitLock) + { + for (int i = _waiters.Count - 1; i >= 0; i--) + { + var waiter = _waiters[i]; + if (waiter.Match(line)) + { + _waiters.RemoveAt(i); + (toFire ??= new List()).Add(waiter); + } + } + } + + if (toFire != null) + foreach (var w in toFire) + w.Tcs.TrySetResult(line); + } + + private async Task SetupBoardAsync(CancellationToken ct) + { + bool auth = await BoardAuthAsync(ct); + if (!auth) + { + Log("Авторизация на плате не пройдена."); + UnityMainThreadDispatcher.Instance.Enqueue(() => Application.Quit()); + return; + } + + _ = StartKeepAliveProcessAsync(ct); + } + + private void OpenPort() + { + Log("Инициализация порта"); + + var ports = ComNativeWrapper.ListPorts(); + if (ports.Length == 0) { Log("Нет портов, завершаю"); return; } + + string port = ports[^1]; + Log("Открываю порт: " + port); + + h = ComNativeWrapper.Serial_Open(port, 115200, 8, 0, 1, 4, 10); + + + Log($"handle: {h}"); + if (h <= 0) + { + Log("Open failed: " + ComNativeWrapper.GetLastError()); + return; + } + else + { + Log($"Открыл порт: {port}"); + } + } + + private async Task BoardAuthAsync(CancellationToken ct) + { + //Проверяем зашифрована или нет + try + { + Send(REQUEST_INPUT_COMMAND); + var inputLine = await WaitForPrefixAsync("INPUT", 1000, ct); + return true; + } + catch (TimeoutException) + { + //Не пришел инпут + Log("Шифрованная плата"); + } + + //Запрашиваем шифрованную строку + string encLine; + try + { + Send(REQUEST_ENCRYPTED_COMMAND); + encLine = await WaitForPrefixAsync("ENC:", 1000, ct); + } + catch + { + Log($"Зашифрованная строка не пришла"); + return false; + } + + //Расшифровка + var encrypted = encLine.Substring(4); + var decrypted = BoardUtility.DecryptSerial(encrypted); + + //Отправляем расшифрованное на подтверждение + try + { + Send(REQUEST_CONFIRMATION_COMMAND + decrypted); + await WaitForContainsAsync("OK", 1000, ct); + return true; + } + catch + { + Log("Подтверждение не пришло"); + return false; + } + } + + public void Shutdown() + { + _lifetimeCts?.Cancel(); + _lifetimeCts?.Dispose(); + _lifetimeCts = null; + + StopReaderThread(); + CancelAllWaiters(); + ClosePort(); + } + + private static void CancelAllWaiters() + { + List snapshot; + lock (_waitLock) + { + snapshot = new List(_waiters); + _waiters.Clear(); + } + foreach (Waiter waiter in snapshot) + { + waiter.Tcs.TrySetCanceled(); + } + } + + private void ClosePort() + { + Log($"Отпускаю порт handle:{h}"); + if (h > 0) + { + ComNativeWrapper.Serial_Close(h); + h = 0; + } + } + + + //Сделать ожидание простоя около минуты на проверку и переподелючение. + private async Task StartKeepAliveProcessAsync(CancellationToken ct) + { + try + { + Log("Запуск асинхронной проверки порта"); + while (!ct.IsCancellationRequested) + { + if (!IsInputIdleTooLong()) + { + await Task.Delay(5000, ct); + continue; + } + + //Пингуем плату + if (!await CheckPortConnectionAsync(ct)) + { + Log("Плата отвалилась. Запускаю переподключение."); + await ReinitializePortAsync(ct); + } + + await Task.Delay(10000, ct); + } + } + catch (OperationCanceledException) + { + Log("Асинхронная проверка порта остановлена"); + } + catch (Exception e) + { + Log($"Ошибка проверки порта: {e.Message}"); + } + } + + + private async Task CheckPortConnectionAsync(CancellationToken ct) + { + try + { + Send(REQUEST_INPUT_COMMAND); + await WaitForPrefixAsync("INPUT", 1000, ct); + return true; + } + catch + { + return false; + } + } + + //реализовать + private async Task ReinitializePortAsync(CancellationToken ct) + { + StopReaderThread(); + CancelAllWaiters(); + ClosePort(); + + OpenPort(); + if (h <= 0) + { + Log($"Ошибка при переподключении."); + return; + } + + + StartReaderThread(); + var auth = await BoardAuthAsync(ct); + if (!auth) + UnityMainThreadDispatcher.Instance.Enqueue(() => (new GameObject()).AddComponent(typeof(VfxPrefab))); + } + + private bool IsInputIdleTooLong() + { + int last = Volatile.Read(ref _lastInputTick); + if (last == 0) return true; + int now = Environment.TickCount; + + // переполнение TickCount тут ок: сравнение интервала < 24 дней работает корректно + int elapsed = unchecked(now - last); + return elapsed >= INPUT_IDLE_BEFORE_PING_MS; + } + + private void Log(string message) => logger?.Log($"CW{message}"); + +} diff --git a/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs.meta b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs.meta new file mode 100644 index 0000000..82a2177 --- /dev/null +++ b/Assets/Scripts/Inputs/ComSystem/PeripheralControllerV2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8d55e8d9065b35429dcf34db1956eb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/happySounds.meta b/Assets/Sounds/happySounds.meta similarity index 100% rename from Assets/happySounds.meta rename to Assets/Sounds/happySounds.meta diff --git a/Assets/happySounds/happy1 (1).mp3 b/Assets/Sounds/happySounds/happy1 (1).mp3 similarity index 100% rename from Assets/happySounds/happy1 (1).mp3 rename to Assets/Sounds/happySounds/happy1 (1).mp3 diff --git a/Assets/happySounds/happy1 (1).mp3.meta b/Assets/Sounds/happySounds/happy1 (1).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (1).mp3.meta rename to Assets/Sounds/happySounds/happy1 (1).mp3.meta diff --git a/Assets/happySounds/happy1 (2).mp3 b/Assets/Sounds/happySounds/happy1 (2).mp3 similarity index 100% rename from Assets/happySounds/happy1 (2).mp3 rename to Assets/Sounds/happySounds/happy1 (2).mp3 diff --git a/Assets/happySounds/happy1 (2).mp3.meta b/Assets/Sounds/happySounds/happy1 (2).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (2).mp3.meta rename to Assets/Sounds/happySounds/happy1 (2).mp3.meta diff --git a/Assets/happySounds/happy1 (3).mp3 b/Assets/Sounds/happySounds/happy1 (3).mp3 similarity index 100% rename from Assets/happySounds/happy1 (3).mp3 rename to Assets/Sounds/happySounds/happy1 (3).mp3 diff --git a/Assets/happySounds/happy1 (3).mp3.meta b/Assets/Sounds/happySounds/happy1 (3).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (3).mp3.meta rename to Assets/Sounds/happySounds/happy1 (3).mp3.meta diff --git a/Assets/happySounds/happy1 (4).mp3 b/Assets/Sounds/happySounds/happy1 (4).mp3 similarity index 100% rename from Assets/happySounds/happy1 (4).mp3 rename to Assets/Sounds/happySounds/happy1 (4).mp3 diff --git a/Assets/happySounds/happy1 (4).mp3.meta b/Assets/Sounds/happySounds/happy1 (4).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (4).mp3.meta rename to Assets/Sounds/happySounds/happy1 (4).mp3.meta diff --git a/Assets/happySounds/happy1 (5).mp3 b/Assets/Sounds/happySounds/happy1 (5).mp3 similarity index 100% rename from Assets/happySounds/happy1 (5).mp3 rename to Assets/Sounds/happySounds/happy1 (5).mp3 diff --git a/Assets/happySounds/happy1 (5).mp3.meta b/Assets/Sounds/happySounds/happy1 (5).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (5).mp3.meta rename to Assets/Sounds/happySounds/happy1 (5).mp3.meta diff --git a/Assets/happySounds/happy1 (6).mp3 b/Assets/Sounds/happySounds/happy1 (6).mp3 similarity index 100% rename from Assets/happySounds/happy1 (6).mp3 rename to Assets/Sounds/happySounds/happy1 (6).mp3 diff --git a/Assets/happySounds/happy1 (6).mp3.meta b/Assets/Sounds/happySounds/happy1 (6).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (6).mp3.meta rename to Assets/Sounds/happySounds/happy1 (6).mp3.meta diff --git a/Assets/happySounds/happy1 (7).mp3 b/Assets/Sounds/happySounds/happy1 (7).mp3 similarity index 100% rename from Assets/happySounds/happy1 (7).mp3 rename to Assets/Sounds/happySounds/happy1 (7).mp3 diff --git a/Assets/happySounds/happy1 (7).mp3.meta b/Assets/Sounds/happySounds/happy1 (7).mp3.meta similarity index 100% rename from Assets/happySounds/happy1 (7).mp3.meta rename to Assets/Sounds/happySounds/happy1 (7).mp3.meta diff --git a/Assets/Prefabs/Хвост.png b/Assets/Sprites/Хвост.png similarity index 100% rename from Assets/Prefabs/Хвост.png rename to Assets/Sprites/Хвост.png diff --git a/Assets/Prefabs/Хвост.png.meta b/Assets/Sprites/Хвост.png.meta similarity index 100% rename from Assets/Prefabs/Хвост.png.meta rename to Assets/Sprites/Хвост.png.meta