Refactor exit handling and command input in TUI

- Improved the exit process by ensuring the backend shutdown is called after handling offline prompts.
- Enhanced command input history management by encapsulating text setting logic in a dedicated method to prevent event handler interference.
- Adjusted the background color in the color parser for better visibility.
- Increased the sleep duration in the TUI exit guard thread to ensure a smoother shutdown process.
This commit is contained in:
BruceChen 2026-03-26 23:20:10 +08:00
parent 0ceaaead10
commit b33ee7e4a1
4 changed files with 79 additions and 67 deletions

View file

@ -774,16 +774,20 @@ namespace MinecraftClient
public static void DoExit(int exitcode = 0)
{
WriteBackSettings();
ConsoleIO.Backend?.Shutdown();
ConsoleIO.WriteLineFormatted("§a" + string.Format(Translations.config_saving, settingsIniPath));
if (client is not null) { client.Disconnect(); ConsoleIO.Reset(); }
if (offlinePrompt is not null)
{
ConsoleIO.Backend.OnInputChange -= ConsoleIO.OfflineAutocompleteHandler;
offlinePrompt.Item2.Cancel(); offlinePrompt.Item1.Join(); offlinePrompt = null; ConsoleIO.Reset();
offlinePrompt.Item2.Cancel();
if (Thread.CurrentThread != offlinePrompt.Item1)
offlinePrompt.Item1.Join(1000);
offlinePrompt = null;
ConsoleIO.Reset();
}
if (Config.Main.Advanced.PlayerHeadAsIcon) { ConsoleIcon.RevertToMCCIcon(); }
ConsoleIO.Backend?.Shutdown();
Environment.Exit(exitcode);
}
@ -804,15 +808,18 @@ namespace MinecraftClient
/// <param name="disconnectReason">If set, the error message will be processed by the AutoRelog bot</param>
public static void HandleFailure(string? errorMessage = null, bool versionError = false, ChatBot.DisconnectReason? disconnectReason = null)
{
if (!String.IsNullOrEmpty(errorMessage))
if (!string.IsNullOrEmpty(errorMessage))
{
ConsoleIO.Reset();
try
if (ConsoleIO.Backend is not Tui.TuiConsoleBackend)
{
while (Console.KeyAvailable)
Console.ReadKey(true);
try
{
while (Console.KeyAvailable)
Console.ReadKey(true);
}
catch { }
}
catch { }
ConsoleIO.WriteLine(errorMessage);
if (disconnectReason.HasValue)
@ -864,65 +871,57 @@ namespace MinecraftClient
if (exitThread)
return;
while (command.Length > 0)
command = ConsoleIO.ReadLine().Trim();
if (command.Length == 0)
{
if (cancellationTokenSource.IsCancellationRequested)
return;
command = ConsoleIO.ReadLine().Trim();
if (command.Length > 0)
{
string message = "";
if (Config.Main.Advanced.InternalCmdChar.ToChar() != ' '
&& command[0] == Config.Main.Advanced.InternalCmdChar.ToChar())
command = command[1..];
if (command.StartsWith("reco"))
{
message = Commands.Reco.DoReconnect(Config.AppVar.ExpandVars(command));
if (message == "")
{
exitThread = true;
break;
}
}
else if (command.StartsWith("connect"))
{
message = Commands.Connect.DoConnect(Config.AppVar.ExpandVars(command));
if (message == "")
{
exitThread = true;
break;
}
}
else if (command.StartsWith("exit") || command.StartsWith("quit"))
{
message = Commands.Exit.DoExit(Config.AppVar.ExpandVars(command));
}
else if (command.StartsWith("help"))
{
ConsoleIO.WriteLineFormatted("§8MCC: " +
Config.Main.Advanced.InternalCmdChar.ToLogString() +
new Commands.Reco().GetCmdDescTranslated());
ConsoleIO.WriteLineFormatted("§8MCC: " +
Config.Main.Advanced.InternalCmdChar.ToLogString() +
new Commands.Connect().GetCmdDescTranslated());
}
else
ConsoleIO.WriteLineFormatted(string.Format(Translations.icmd_unknown, command.Split(' ')[0]));
if (message != "")
ConsoleIO.WriteLineFormatted("§8MCC: " + message);
}
else
{
if (ConsoleIO.Backend is not Tui.TuiConsoleBackend)
Commands.Exit.DoExit(Config.AppVar.ExpandVars(command));
}
continue;
}
if (exitThread)
return;
string message = "";
if (Config.Main.Advanced.InternalCmdChar.ToChar() != ' '
&& command[0] == Config.Main.Advanced.InternalCmdChar.ToChar())
command = command[1..];
if (command.StartsWith("reco"))
{
message = Commands.Reco.DoReconnect(Config.AppVar.ExpandVars(command));
if (message == "")
{
exitThread = true;
continue;
}
}
else if (command.StartsWith("connect"))
{
message = Commands.Connect.DoConnect(Config.AppVar.ExpandVars(command));
if (message == "")
{
exitThread = true;
continue;
}
}
else if (command.StartsWith("exit") || command.StartsWith("quit"))
{
message = Commands.Exit.DoExit(Config.AppVar.ExpandVars(command));
}
else if (command.StartsWith("help"))
{
ConsoleIO.WriteLineFormatted("§8MCC: " +
Config.Main.Advanced.InternalCmdChar.ToLogString() +
new Commands.Reco().GetCmdDescTranslated());
ConsoleIO.WriteLineFormatted("§8MCC: " +
Config.Main.Advanced.InternalCmdChar.ToLogString() +
new Commands.Connect().GetCmdDescTranslated());
}
else
ConsoleIO.WriteLineFormatted(string.Format(Translations.icmd_unknown, command.Split(' ')[0]));
if (message != "")
ConsoleIO.WriteLineFormatted("§8MCC: " + message);
}
})), cancellationTokenSource);
offlinePrompt.Item1.Start();

View file

@ -494,10 +494,21 @@ namespace MinecraftClient.Tui
}
string historyText = _commandHistory[_historyIndex];
_commandInput.Text = historyText;
_commandInput.CaretIndex = historyText.Length;
Dispatcher.UIThread.Post(() => _commandInput.CaretIndex = historyText.Length,
DispatcherPriority.Input);
SetCommandText(historyText);
}
private void SetCommandText(string text)
{
_commandInput.TextChanged -= OnCommandTextChanged;
try
{
_commandInput.Text = text;
_commandInput.CaretIndex = text.Length;
}
finally
{
_commandInput.TextChanged += OnCommandTextChanged;
}
}
#endregion

View file

@ -47,6 +47,8 @@ namespace MinecraftClient.Tui
return tb;
}
tb.Background = Brushes.Black;
IBrush currentColor = Brushes.White;
bool bold = false;
bool italic = false;

View file

@ -256,7 +256,7 @@ namespace MinecraftClient.Tui
new Thread(() =>
{
Thread.Sleep(500);
Thread.Sleep(1000);
Environment.Exit(0);
}) { Name = "TUI-Exit-Guard", IsBackground = true }.Start();
}