181 lines
5.7 KiB
C#
181 lines
5.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
public static class BlinkStartupInitializer
|
|
{
|
|
private const string ConfigFileName = "led_startup_config.ini";
|
|
private static bool subscribed;
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void Register()
|
|
{
|
|
if (subscribed)
|
|
return;
|
|
|
|
subscribed = true;
|
|
ComWrapper.OnInitialize += ApplyStartupCommands;
|
|
Application.quitting += Unregister;
|
|
}
|
|
|
|
private static void Unregister()
|
|
{
|
|
ComWrapper.OnInitialize -= ApplyStartupCommands;
|
|
Application.quitting -= Unregister;
|
|
subscribed = false;
|
|
}
|
|
|
|
private static void ApplyStartupCommands()
|
|
{
|
|
string configPath = Path.Combine(Application.streamingAssetsPath, ConfigFileName);
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(configPath))
|
|
{
|
|
Directory.CreateDirectory(Application.streamingAssetsPath);
|
|
File.WriteAllText(configPath, GetDefaultConfig());
|
|
Debug.Log($"BlinkStartupInitializer: создан файл конфигурации {configPath}");
|
|
}
|
|
|
|
string[] lines = File.ReadAllLines(configPath);
|
|
for (int i = 0; i < lines.Length; i++)
|
|
ProcessLine(lines[i], i + 1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"BlinkStartupInitializer: ошибка чтения {configPath}: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private static void ProcessLine(string rawLine, int lineNumber)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(rawLine))
|
|
return;
|
|
|
|
string line = StripComments(rawLine).Trim();
|
|
if (string.IsNullOrWhiteSpace(line))
|
|
return;
|
|
|
|
int separatorIndex = line.IndexOf('=');
|
|
if (separatorIndex < 0)
|
|
{
|
|
Debug.LogWarning($"BlinkStartupInitializer: строка {lineNumber} должна быть в формате player1=004 003");
|
|
return;
|
|
}
|
|
|
|
string playerToken = line.Substring(0, separatorIndex).Trim();
|
|
string commandsToken = line.Substring(separatorIndex + 1).Trim();
|
|
|
|
if (!TryParsePlayerId(playerToken, out int playerId))
|
|
{
|
|
Debug.LogWarning($"BlinkStartupInitializer: строка {lineNumber}, неизвестный идентификатор '{playerToken}'");
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(commandsToken))
|
|
{
|
|
Debug.LogWarning($"BlinkStartupInitializer: строка {lineNumber} не содержит команд");
|
|
return;
|
|
}
|
|
|
|
string[] commands = commandsToken.Split(new[] { ' ', '\t', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (string command in commands)
|
|
SendValidatedCommand(command, playerId, lineNumber);
|
|
}
|
|
|
|
private static void SendValidatedCommand(string rawCommand, int playerId, int lineNumber)
|
|
{
|
|
if (!TryNormalizeCommand(rawCommand, out string command))
|
|
{
|
|
Debug.LogWarning($"BlinkStartupInitializer: строка {lineNumber}, команда '{rawCommand}' некорректна");
|
|
return;
|
|
}
|
|
|
|
ComWrapper.Send(command, playerId);
|
|
Debug.Log($"BlinkStartupInitializer: отправлена команда {command} для playerId={playerId}");
|
|
}
|
|
|
|
private static bool TryNormalizeCommand(string rawCommand, out string command)
|
|
{
|
|
command = null;
|
|
if (string.IsNullOrWhiteSpace(rawCommand))
|
|
return false;
|
|
|
|
string value = rawCommand.Trim();
|
|
if (value.StartsWith("89", StringComparison.Ordinal))
|
|
value = value.Substring(2);
|
|
|
|
if (value.Length != 3)
|
|
return false;
|
|
|
|
if (!char.IsDigit(value[0]) || !char.IsDigit(value[1]) || !char.IsDigit(value[2]))
|
|
return false;
|
|
|
|
int channel = value[0] - '0';
|
|
int mode = value[1] - '0';
|
|
int sequence = value[2] - '0';
|
|
|
|
if (channel < 0 || channel > 4)
|
|
return false;
|
|
|
|
if (mode != 0)
|
|
return false;
|
|
|
|
if (sequence < 0 || sequence > 5)
|
|
return false;
|
|
|
|
command = $"89{value}";
|
|
return true;
|
|
}
|
|
|
|
private static bool TryParsePlayerId(string token, out int playerId)
|
|
{
|
|
switch (token.Trim().ToLowerInvariant())
|
|
{
|
|
case "1":
|
|
case "player1":
|
|
case "plate1":
|
|
playerId = 1;
|
|
return true;
|
|
case "2":
|
|
case "player2":
|
|
case "plate2":
|
|
playerId = 2;
|
|
return true;
|
|
default:
|
|
playerId = 0;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static string StripComments(string line)
|
|
{
|
|
int hashIndex = line.IndexOf('#');
|
|
int slashIndex = line.IndexOf("//", StringComparison.Ordinal);
|
|
|
|
int commentIndex = -1;
|
|
if (hashIndex >= 0)
|
|
commentIndex = hashIndex;
|
|
if (slashIndex >= 0 && (commentIndex < 0 || slashIndex < commentIndex))
|
|
commentIndex = slashIndex;
|
|
|
|
return commentIndex >= 0 ? line.Substring(0, commentIndex) : line;
|
|
}
|
|
|
|
private static string GetDefaultConfig()
|
|
{
|
|
return string.Join(Environment.NewLine, new[]
|
|
{
|
|
"# Команды инициализации LED-лент.",
|
|
"# Формат: player1=004 003",
|
|
"# player1/player2 = номер платы = playerId",
|
|
"# Команда: X0Z или 89X0Z",
|
|
"# X: 0 - все каналы, 1-4 - конкретный канал",
|
|
"# Z: 0-RGB, 1-RBG, 2-BRG, 3-BGR, 4-GRB, 5-GBR",
|
|
"player1=004",
|
|
"player2=004"
|
|
});
|
|
}
|
|
}
|