mirror of
https://github.com/MikuLeaks/KianaBH3.git
synced 2025-12-12 13:04:33 +01:00
185 lines
5.5 KiB
C#
185 lines
5.5 KiB
C#
using Kodnix.Character;
|
|
|
|
namespace KianaBH.Util;
|
|
|
|
public class IConsole
|
|
{
|
|
public static readonly string PrefixContent = "[KianaBH]> ";
|
|
public static readonly string Prefix = $"\u001b[38;2;255;192;203m{PrefixContent}\u001b[0m";
|
|
private static readonly int HistoryMaxCount = 10;
|
|
|
|
public static List<char> Input { get; set; } = [];
|
|
private static int CursorIndex { get; set; } = 0;
|
|
private static readonly List<string> InputHistory = [];
|
|
private static int HistoryIndex = -1;
|
|
|
|
public static event Action<string>? OnConsoleExcuteCommand;
|
|
|
|
public static void InitConsole()
|
|
{
|
|
Console.Title = ConfigManager.Config.GameServer.GameServerName;
|
|
}
|
|
|
|
public static int GetWidth(string str)
|
|
=> str.ToCharArray().Sum(EastAsianWidth.GetLength);
|
|
|
|
public static void RedrawInput(List<char> input, bool hasPrefix = true)
|
|
=> RedrawInput(new string([.. input]), hasPrefix);
|
|
|
|
public static void RedrawInput(string input, bool hasPrefix = true)
|
|
{
|
|
var length = GetWidth(input);
|
|
if (hasPrefix)
|
|
{
|
|
input = Prefix + input;
|
|
length += GetWidth(PrefixContent);
|
|
}
|
|
|
|
if (Console.GetCursorPosition().Left > 0)
|
|
Console.SetCursorPosition(0, Console.CursorTop);
|
|
|
|
Console.Write(input + new string(' ', Console.BufferWidth - length));
|
|
Console.SetCursorPosition(length, Console.CursorTop);
|
|
}
|
|
|
|
#region Handlers
|
|
|
|
public static void HandleEnter()
|
|
{
|
|
var input = new string([.. Input]);
|
|
if (string.IsNullOrWhiteSpace(input)) return;
|
|
|
|
// New line
|
|
Console.WriteLine();
|
|
Input = [];
|
|
CursorIndex = 0;
|
|
if (InputHistory.Count >= HistoryMaxCount)
|
|
InputHistory.RemoveAt(0);
|
|
InputHistory.Add(input);
|
|
HistoryIndex = InputHistory.Count;
|
|
|
|
// Handle command
|
|
if (input.StartsWith('/')) input = input[1..].Trim();
|
|
OnConsoleExcuteCommand?.Invoke(input);
|
|
}
|
|
|
|
public static void HandleBackspace()
|
|
{
|
|
if (CursorIndex <= 0) return;
|
|
CursorIndex--;
|
|
var targetWidth = GetWidth(Input[CursorIndex].ToString());
|
|
Input.RemoveAt(CursorIndex);
|
|
|
|
var (left, _) = Console.GetCursorPosition();
|
|
Console.SetCursorPosition(left - targetWidth, Console.CursorTop);
|
|
var remain = new string([.. Input.Skip(CursorIndex)]);
|
|
Console.Write(remain + new string(' ', targetWidth));
|
|
Console.SetCursorPosition(left - targetWidth, Console.CursorTop);
|
|
}
|
|
|
|
public static void HandleUpArrow()
|
|
{
|
|
if (InputHistory.Count == 0) return;
|
|
|
|
if (HistoryIndex > 0)
|
|
{
|
|
HistoryIndex--;
|
|
var history = InputHistory[HistoryIndex];
|
|
Input = [.. history];
|
|
CursorIndex = Input.Count;
|
|
RedrawInput(Input);
|
|
}
|
|
}
|
|
|
|
public static void HandleDownArrow()
|
|
{
|
|
if (HistoryIndex >= InputHistory.Count) return;
|
|
|
|
HistoryIndex++;
|
|
if (HistoryIndex >= InputHistory.Count)
|
|
{
|
|
HistoryIndex = InputHistory.Count;
|
|
Input = [];
|
|
CursorIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
var history = InputHistory[HistoryIndex];
|
|
Input = [.. history];
|
|
CursorIndex = Input.Count;
|
|
}
|
|
RedrawInput(Input);
|
|
}
|
|
|
|
public static void HandleLeftArrow()
|
|
{
|
|
if (CursorIndex <= 0) return;
|
|
|
|
var (left, _) = Console.GetCursorPosition();
|
|
CursorIndex--;
|
|
Console.SetCursorPosition(left - GetWidth(Input[CursorIndex].ToString()), Console.CursorTop);
|
|
}
|
|
|
|
public static void HandleRightArrow()
|
|
{
|
|
if (CursorIndex >= Input.Count) return;
|
|
|
|
var (left, _) = Console.GetCursorPosition();
|
|
CursorIndex++;
|
|
Console.SetCursorPosition(left + GetWidth(Input[CursorIndex - 1].ToString()), Console.CursorTop);
|
|
}
|
|
|
|
public static void HandleInput(ConsoleKeyInfo keyInfo)
|
|
{
|
|
if (char.IsControl(keyInfo.KeyChar)) return;
|
|
if (Input.Count >= (Console.BufferWidth - PrefixContent.Length)) return;
|
|
HandleInput(keyInfo.KeyChar);
|
|
}
|
|
|
|
public static void HandleInput(char keyChar)
|
|
{
|
|
Input.Insert(CursorIndex, keyChar);
|
|
CursorIndex++;
|
|
|
|
var (left, _) = Console.GetCursorPosition();
|
|
Console.Write(new string([.. Input.Skip(CursorIndex - 1)]));
|
|
Console.SetCursorPosition(left + GetWidth(keyChar.ToString()), Console.CursorTop);
|
|
}
|
|
|
|
#endregion
|
|
|
|
public static string ListenConsole()
|
|
{
|
|
while (true)
|
|
{
|
|
ConsoleKeyInfo keyInfo;
|
|
try { keyInfo = Console.ReadKey(true); }
|
|
catch (InvalidOperationException) { continue; }
|
|
|
|
switch (keyInfo.Key)
|
|
{
|
|
case ConsoleKey.Enter:
|
|
HandleEnter();
|
|
break;
|
|
case ConsoleKey.Backspace:
|
|
HandleBackspace();
|
|
break;
|
|
case ConsoleKey.LeftArrow:
|
|
HandleLeftArrow();
|
|
break;
|
|
case ConsoleKey.RightArrow:
|
|
HandleRightArrow();
|
|
break;
|
|
case ConsoleKey.UpArrow:
|
|
HandleUpArrow();
|
|
break;
|
|
case ConsoleKey.DownArrow:
|
|
HandleDownArrow();
|
|
break;
|
|
default:
|
|
HandleInput(keyInfo);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} |