Process command prompt text on main thread (#1510)

Fix possible threading issues when MCC commands interactively
This commit is contained in:
ORelio 2021-03-27 19:15:58 +01:00
parent 47c19466c3
commit 70d3b6175b

View file

@ -26,7 +26,9 @@ namespace MinecraftClient
private static readonly List<string> cmd_names = new List<string>();
private static readonly Dictionary<string, Command> cmds = new Dictionary<string, Command>();
private readonly Dictionary<Guid, string> onlinePlayers = new Dictionary<Guid, string>();
private static bool CommandLoaded = false;
private static bool commandsLoaded = false;
private Queue<string> commandQueue = new Queue<string>();
private Queue<string> chatQueue = new Queue<string>();
private static DateTime nextMessageSendTime = DateTime.MinValue;
@ -289,19 +291,33 @@ namespace MinecraftClient
}
/// <summary>
/// Allows the user to send chat messages, commands, and to leave the server.
/// Allows the user to send chat messages, commands, and leave the server.
/// Enqueue text typed in the command prompt for processing on the main thread.
/// </summary>
private void CommandPrompt()
{
try
{
string text = "";
Thread.Sleep(500);
handler.SendRespawnPacket();
while (client.Client.Connected)
{
text = ConsoleIO.ReadLine();
string text = ConsoleIO.ReadLine();
lock (commandQueue)
{
commandQueue.Enqueue(text);
}
}
}
catch (IOException) { }
catch (NullReferenceException) { }
}
/// <summary>
/// Allows the user to send chat messages, commands, and leave the server.
/// Process text from the MCC command prompt on the main thread.
/// </summary>
private void HandleCommandPromptText(string text)
{
if (ConsoleIO.BasicIO && text.Length > 0 && text[0] == (char)0x00)
{
//Process a request from the GUI
@ -336,10 +352,6 @@ namespace MinecraftClient
}
}
}
}
catch (IOException) { }
catch (NullReferenceException) { }
}
/// <summary>
/// Periodically checks for server keepalives and consider that connection has been lost if the last received keepalive is too old.
@ -426,7 +438,7 @@ namespace MinecraftClient
{
/* Load commands from the 'Commands' namespace */
if (!CommandLoaded)
if (!commandsLoaded)
{
Type[] cmds_classes = Program.GetTypesInNamespace("MinecraftClient.Commands");
foreach (Type type in cmds_classes)
@ -447,7 +459,7 @@ namespace MinecraftClient
}
}
}
CommandLoaded = true;
commandsLoaded = true;
}
}
@ -560,6 +572,14 @@ namespace MinecraftClient
}
}
lock (commandQueue)
{
if (commandQueue.Count > 0)
{
HandleCommandPromptText(commandQueue.Dequeue());
}
}
lock (chatQueue)
{
if (chatQueue.Count > 0 && nextMessageSendTime < DateTime.Now)