- Добавлен ComSystemManager как новый публичный компонент COM-системы для поэтапной замены ComWrapper - Реализовано получение роли контроллера только после успешного handshake в ComDeviceClient - Добавлено публичное поле ControllerRole в ComDeviceClient - Добавлен запрос роли по команде 97 и разбор ответа формата ROLE : <value> (с пробелами) - В ComMultiManager добавлена логика выбора DefaultDeviceId по роли main_controller - Добавлен доступ к роли устройства через GetDeviceRole(deviceId) в менеджере и фасаде - В ComWrapper добавлены настройки роли: roleRequestCommand, roleResponsePrefix, roleRequestTimeoutMs, mainControllerRole - Дефолтная команда запроса роли изменена на 97 - Выполнена кодовая миграция зависимостей с ComWrapper на ComSystemManager в GameManager, GlobalsManager, PaymentManager, BalanceManager, InactivityManager, COMInput, LightController, PrizeSystem - В GlobalsManager исправлена инициализация ссылки после AddComponent<ComSystemManager>(), чтобы исключить NullReference
232 lines
7.7 KiB
C#
232 lines
7.7 KiB
C#
using System;
|
|
using RR.Game2D.Core.Managers;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace RR.Common.Controls
|
|
{
|
|
/// <summary>
|
|
/// Совместимый фасад над мульти-устройственной COM-системой.
|
|
/// Старый API сохранен для текущего проекта.
|
|
/// </summary>
|
|
public class ComWrapper : MonoBehaviour
|
|
{
|
|
[Header("Основные настройки")]
|
|
[SerializeField] private bool saveMoneyBetweenSessions;
|
|
[SerializeField] private bool enablePrizeChecking;
|
|
[SerializeField] private bool keepAlive = true;
|
|
|
|
[Header("Авторизация")]
|
|
[SerializeField] private bool enableEncryptedHandshake = true;
|
|
[SerializeField] private int handshakeTimeoutMs = 5000;
|
|
|
|
[Header("Роль контроллера (после handshake)")]
|
|
[SerializeField] private string roleRequestCommand = "97";
|
|
[SerializeField] private string roleResponsePrefix = "ROLE";
|
|
[SerializeField] private int roleRequestTimeoutMs = 1500;
|
|
[SerializeField] private string mainControllerRole = "main_controller";
|
|
|
|
[Header("Мульти-устройства")]
|
|
[SerializeField] private bool useAllDetectedPorts = true;
|
|
[SerializeField] private string[] explicitPorts = Array.Empty<string>();
|
|
[SerializeField] private string defaultDevicePort = "";
|
|
|
|
public static UnityEvent<int> OnCreditAdded;
|
|
public static UnityEvent<int> OnCreditRemoved;
|
|
public static UnityEvent<string> OnInputReceived;
|
|
public static Action OnInitialize;
|
|
|
|
public static UnityEvent<string, string> OnDeviceInputReceived;
|
|
public static UnityEvent<string> OnDeviceAuthorized;
|
|
|
|
private static ComWrapper _instance;
|
|
private static int _creditsCount;
|
|
|
|
private ComMultiManager _manager;
|
|
private LightController _light;
|
|
private bool _initializeInvoked;
|
|
|
|
public LightController Light => _light;
|
|
|
|
public void Initialize()
|
|
{
|
|
_instance = this;
|
|
|
|
OnCreditAdded = new UnityEvent<int>();
|
|
OnCreditRemoved = new UnityEvent<int>();
|
|
OnInputReceived = new UnityEvent<string>();
|
|
OnDeviceInputReceived = new UnityEvent<string, string>();
|
|
OnDeviceAuthorized = new UnityEvent<string>();
|
|
|
|
if (!saveMoneyBetweenSessions) PlayerPrefs.SetInt("CoinsCount", 0);
|
|
_creditsCount = PlayerPrefs.GetInt("CoinsCount", 0);
|
|
|
|
_light = GetComponent<LightController>() ?? gameObject.AddComponent<LightController>();
|
|
|
|
_manager = new ComMultiManager(
|
|
useAllDetectedPorts,
|
|
explicitPorts,
|
|
defaultDevicePort,
|
|
enableEncryptedHandshake,
|
|
handshakeTimeoutMs,
|
|
keepAlive || enablePrizeChecking,
|
|
roleRequestCommand,
|
|
roleResponsePrefix,
|
|
roleRequestTimeoutMs,
|
|
mainControllerRole);
|
|
|
|
_manager.InitializeDevices();
|
|
}
|
|
|
|
public static void AddCredit()
|
|
{
|
|
_creditsCount++;
|
|
PlayerPrefs.SetInt("CoinsCount", _creditsCount);
|
|
OnCreditAdded?.Invoke(_creditsCount);
|
|
}
|
|
|
|
public static bool Pay(int amount = 1)
|
|
{
|
|
if (_creditsCount < amount)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_creditsCount -= amount;
|
|
PlayerPrefs.SetInt("CoinsCount", _creditsCount);
|
|
|
|
PlayerPrefs.SetInt(PrizeSystem.key_starts, PlayerPrefs.GetInt(PrizeSystem.key_starts) + 1);
|
|
PlayerPrefs.SetInt(PrizeSystem.key_startsNul, PlayerPrefs.GetInt(PrizeSystem.key_startsNul) + 1);
|
|
|
|
OnCreditRemoved?.Invoke(_creditsCount);
|
|
return true;
|
|
}
|
|
|
|
public static int GetCredits() => _creditsCount;
|
|
|
|
public static void SetCredits(int amount)
|
|
{
|
|
int oldCredits = _creditsCount;
|
|
_creditsCount = Mathf.Max(0, amount);
|
|
PlayerPrefs.SetInt("CoinsCount", _creditsCount);
|
|
|
|
if (_creditsCount > oldCredits)
|
|
{
|
|
OnCreditAdded?.Invoke(_creditsCount);
|
|
}
|
|
else if (_creditsCount < oldCredits)
|
|
{
|
|
OnCreditRemoved?.Invoke(_creditsCount);
|
|
}
|
|
}
|
|
|
|
public static void Send(string message)
|
|
{
|
|
if (_instance == null || string.IsNullOrWhiteSpace(message)) return;
|
|
_instance._manager?.SendToDefault(message);
|
|
}
|
|
|
|
public static void SendToDevice(string deviceId, string message)
|
|
{
|
|
if (_instance == null || string.IsNullOrWhiteSpace(message)) return;
|
|
_instance._manager?.SendToDevice(deviceId, message);
|
|
}
|
|
|
|
public static void SendToAll(string message)
|
|
{
|
|
if (_instance == null || string.IsNullOrWhiteSpace(message)) return;
|
|
_instance._manager?.SendToAll(message);
|
|
}
|
|
|
|
public static string GetLastInputState()
|
|
{
|
|
if (_instance?._manager == null) return "11111111111111111111111111";
|
|
string defaultId = _instance._manager.DefaultDeviceId;
|
|
return string.IsNullOrWhiteSpace(defaultId)
|
|
? "11111111111111111111111111"
|
|
: _instance._manager.GetLastInputState(defaultId);
|
|
}
|
|
|
|
public static string GetLastInputState(string deviceId)
|
|
{
|
|
return _instance?._manager?.GetLastInputState(deviceId) ?? "11111111111111111111111111";
|
|
}
|
|
|
|
public static string[] GetConnectedDeviceIds()
|
|
{
|
|
return _instance?._manager?.ConnectedDeviceIds ?? Array.Empty<string>();
|
|
}
|
|
|
|
public static string GetDefaultDeviceId()
|
|
{
|
|
return _instance?._manager?.DefaultDeviceId ?? string.Empty;
|
|
}
|
|
|
|
public static string GetDeviceRole(string deviceId)
|
|
{
|
|
return _instance?._manager?.GetDeviceRole(deviceId) ?? string.Empty;
|
|
}
|
|
|
|
public void Blink() => _light.Blink();
|
|
|
|
public void StopBlink(bool enableHat = true) => _light.StopBlink(enableHat);
|
|
|
|
private void Update()
|
|
{
|
|
if (_manager == null) return;
|
|
|
|
int coinsProcessed = 0;
|
|
while (_manager.TryDequeueCoin(out _))
|
|
{
|
|
AddCredit();
|
|
coinsProcessed++;
|
|
}
|
|
|
|
while (_manager.TryDequeueInput(out DeviceInputMessage msg))
|
|
{
|
|
OnDeviceInputReceived?.Invoke(msg.DeviceId, msg.InputBits);
|
|
|
|
if (msg.DeviceId == _manager.DefaultDeviceId)
|
|
{
|
|
OnInputReceived?.Invoke(msg.InputBits);
|
|
}
|
|
}
|
|
|
|
while (_manager.TryDequeueAuthorized(out string deviceId))
|
|
{
|
|
OnDeviceAuthorized?.Invoke(deviceId);
|
|
|
|
if (!_initializeInvoked)
|
|
{
|
|
_initializeInvoked = true;
|
|
OnInitialize?.Invoke();
|
|
}
|
|
|
|
if (deviceId == _manager.DefaultDeviceId)
|
|
{
|
|
_light.Blink();
|
|
}
|
|
}
|
|
|
|
if (coinsProcessed > 0)
|
|
{
|
|
GameManager.Logger?.Log("ComWrapper", $"Обработано монет: {coinsProcessed}");
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_manager?.ShutdownAll(false);
|
|
_manager = null;
|
|
_initializeInvoked = false;
|
|
}
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
_manager?.ShutdownAll(true);
|
|
_manager = null;
|
|
_initializeInvoked = false;
|
|
}
|
|
}
|
|
}
|