diff --git a/MinecraftClient/ConsoleIO.cs b/MinecraftClient/ConsoleIO.cs index 65488382..b720c088 100644 --- a/MinecraftClient/ConsoleIO.cs +++ b/MinecraftClient/ConsoleIO.cs @@ -16,6 +16,7 @@ namespace MinecraftClient { public static bool basicIO = false; private static IAutoComplete autocomplete_engine; + private static LinkedList autocomplete_words = new LinkedList(); private static LinkedList previous = new LinkedList(); private static readonly object io_lock = new object(); private static bool reading = false; @@ -168,14 +169,20 @@ namespace MinecraftClient } break; case ConsoleKey.Tab: - if (autocomplete_engine != null && buffer.Length > 0) + if (autocomplete_words.Count == 0 && autocomplete_engine != null && buffer.Length > 0) + foreach (string result in autocomplete_engine.AutoComplete(buffer)) + autocomplete_words.AddLast(result); + string word_autocomplete = null; + if (autocomplete_words.Count > 0) { - string word_autocomplete = autocomplete_engine.AutoComplete(buffer); - if (!String.IsNullOrEmpty(word_autocomplete) && word_autocomplete != buffer) - { - while (buffer.Length > 0 && buffer[buffer.Length - 1] != ' ') { RemoveOneChar(); } - foreach (char c in word_autocomplete) { AddChar(c); } - } + word_autocomplete = autocomplete_words.First.Value; + autocomplete_words.RemoveFirst(); + autocomplete_words.AddLast(word_autocomplete); + } + if (!String.IsNullOrEmpty(word_autocomplete) && word_autocomplete != buffer) + { + while (buffer.Length > 0 && buffer[buffer.Length - 1] != ' ') { RemoveOneChar(); } + foreach (char c in word_autocomplete) { AddChar(c); } } break; default: @@ -184,6 +191,8 @@ namespace MinecraftClient break; } } + if (k.Key != ConsoleKey.Tab) + autocomplete_words.Clear(); } } @@ -444,6 +453,6 @@ namespace MinecraftClient public interface IAutoComplete { - string AutoComplete(string BehindCursor); + IEnumerable AutoComplete(string BehindCursor); } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 14dce500..c5f002c3 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -656,10 +656,10 @@ namespace MinecraftClient.Protocol.Handlers catch (System.IO.IOException) { return false; } } - public string AutoComplete(string BehindCursor) + IEnumerable IAutoComplete.AutoComplete(string BehindCursor) { if (String.IsNullOrEmpty(BehindCursor)) - return ""; + return new string[] { }; byte[] autocomplete = new byte[3 + (BehindCursor.Length * 2)]; autocomplete[0] = 0xCB; @@ -674,8 +674,9 @@ namespace MinecraftClient.Protocol.Handlers int wait_left = 50; //do not wait more than 5 seconds (50 * 100 ms) while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; } - string[] results = autocomplete_result.Split((char)0x00); - return results[0]; + if (!String.IsNullOrEmpty(autocomplete_result) && autocomplete_received) + ConsoleIO.WriteLineFormatted("§8" + autocomplete_result.Replace((char)0x00, ' '), false); + return autocomplete_result.Split((char)0x00); } private static byte[] concatBytes(params byte[][] bytes) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 4e804390..81c16321 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -23,7 +23,7 @@ namespace MinecraftClient.Protocol.Handlers private int compression_treshold = 0; private bool autocomplete_received = false; - private string autocomplete_result = ""; + private readonly List autocomplete_result = new List(); private bool login_phase = true; private bool encrypted = false; private int protocolversion; @@ -393,17 +393,10 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketIncomingType.TabCompleteResult: int autocomplete_count = readNextVarInt(packetData); - string tab_list = ""; + autocomplete_result.Clear(); for (int i = 0; i < autocomplete_count; i++) - { - autocomplete_result = readNextString(packetData); - if (autocomplete_result != "") - tab_list = tab_list + autocomplete_result + " "; - } + autocomplete_result.Add(readNextString(packetData)); autocomplete_received = true; - tab_list = tab_list.Trim(); - if (tab_list.Length > 0) - ConsoleIO.WriteLineFormatted("§8" + tab_list, false); break; case PacketIncomingType.PluginMessage: String channel = readNextString(packetData); @@ -1331,10 +1324,10 @@ namespace MinecraftClient.Protocol.Handlers /// Text behind cursor /// Completed text - public string AutoComplete(string BehindCursor) + IEnumerable IAutoComplete.AutoComplete(string BehindCursor) { if (String.IsNullOrEmpty(BehindCursor)) - return ""; + return new string[] { }; byte[] tocomplete_val = Encoding.UTF8.GetBytes(BehindCursor); byte[] tocomplete_len = getVarInt(tocomplete_val.Length); @@ -1347,11 +1340,14 @@ namespace MinecraftClient.Protocol.Handlers : concatBytes(tocomplete_len, tocomplete_val); autocomplete_received = false; - autocomplete_result = BehindCursor; + autocomplete_result.Clear(); + autocomplete_result.Add(BehindCursor); SendPacket(protocolversion >= MC19Version ? 0x01 : 0x14, tabcomplete_packet); int wait_left = 50; //do not wait more than 5 seconds (50 * 100 ms) while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; } + if (autocomplete_result.Count > 0) + ConsoleIO.WriteLineFormatted("§8" + String.Join(" ", autocomplete_result), false); return autocomplete_result; }