using System; using System.Collections.Generic; using System.Threading; using Spectre.Console; namespace Generator.Commands { public sealed class AsciiCastInput : IAnsiConsoleInput { private readonly Queue<(ConsoleKeyInfo?, int)> _input; private readonly Random _random = new Random(); public AsciiCastInput() { _input = new Queue<(ConsoleKeyInfo?, int)>(); } public void PushText(string input, int keypressDelayMs) { if (input is null) { throw new ArgumentNullException(nameof(input)); } foreach (var character in input) { PushCharacter(character, keypressDelayMs); } } public void PushTextWithEnter(string input, int keypressDelayMs) { PushText(input, keypressDelayMs); PushKey(ConsoleKey.Enter, keypressDelayMs); } public void PushCharacter(char input, int keypressDelayMs) { var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2)); switch (input) { case '↑': PushKey(ConsoleKey.UpArrow, keypressDelayMs); break; case '↓': PushKey(ConsoleKey.DownArrow, keypressDelayMs); break; case '↲': PushKey(ConsoleKey.Enter, keypressDelayMs); break; case '¦': _input.Enqueue((null, delay)); break; default: var control = char.IsUpper(input); _input.Enqueue((new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control), delay)); break; } } public void PushKey(ConsoleKey input, int keypressDelayMs) { var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2)); _input.Enqueue((new ConsoleKeyInfo((char)input, input, false, false, false), delay)); } public ConsoleKeyInfo? ReadKey(bool intercept) { if (_input.Count == 0) { throw new InvalidOperationException("No input available."); } var result = _input.Dequeue(); Thread.Sleep(result.Item2); return result.Item1; } } }