diff --git a/MinecraftClient/ChatBots/Alerts.cs b/MinecraftClient/ChatBots/Alerts.cs
index 9ad12b2b..b79df8b3 100644
--- a/MinecraftClient/ChatBots/Alerts.cs
+++ b/MinecraftClient/ChatBots/Alerts.cs
@@ -41,7 +41,7 @@ namespace MinecraftClient.ChatBots
if (Settings.Alerts_Beep_Enabled)
Console.Beep(); //Text found !
- if (ConsoleIO.basicIO) //Using a GUI? Pass text as is.
+ if (ConsoleIO.BasicIO) //Using a GUI? Pass text as is.
ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r"));
else //Using Console Prompt : Print text with alert highlighted
diff --git a/MinecraftClient/ConsoleIO.cs b/MinecraftClient/ConsoleIO.cs
index 4d945c31..225416a9 100644
--- a/MinecraftClient/ConsoleIO.cs
+++ b/MinecraftClient/ConsoleIO.cs
@@ -10,10 +10,11 @@ namespace MinecraftClient
///
/// Allows simultaneous console input and output without breaking user input
/// (Without having this annoying behaviour : User inp[Some Console output]ut)
+ /// Provide some fancy features such as formatted output, text pasting and tab-completion.
+ /// By ORelio - (c) 2012-2018 - Available under the CDDL-1.0 license
///
public static class ConsoleIO
{
- public static bool basicIO = false;
private static IAutoComplete autocomplete_engine;
private static LinkedList autocomplete_words = new LinkedList();
private static LinkedList previous = new LinkedList();
@@ -38,6 +39,32 @@ namespace MinecraftClient
}
}
+ ///
+ /// Set an auto-completion engine for TAB autocompletion.
+ ///
+ /// Engine implementing the IAutoComplete interface
+ public static void SetAutoCompleteEngine(IAutoComplete engine)
+ {
+ autocomplete_engine = engine;
+ }
+
+ ///
+ /// Determines whether to use interactive IO or basic IO.
+ /// Set to true to disable interactive command prompt and use the default Console.Read|Write() methods.
+ /// Color codes are printed as is when BasicIO is enabled.
+ ///
+ public static bool BasicIO = false;
+
+ ///
+ /// Determine whether WriteLineFormatted() should prepend lines with timestamps by default.
+ ///
+ public static bool EnableTimestamps = false;
+
+ ///
+ /// Specify a generic log line prefix for WriteLogLine()
+ ///
+ public static string LogPrefix = "§8[Log] ";
+
///
/// Read a password from the standard input
///
@@ -88,7 +115,11 @@ namespace MinecraftClient
///
public static string ReadLine()
{
- if (basicIO) { return Console.ReadLine(); }
+ if (BasicIO)
+ {
+ return Console.ReadLine();
+ }
+
ConsoleKeyInfo k = new ConsoleKeyInfo();
lock (io_lock)
@@ -199,7 +230,7 @@ namespace MinecraftClient
}
///
- /// Debug routine
+ /// Debug routine: print all keys pressed in the console
///
public static void DebugReadInput()
{
@@ -216,7 +247,7 @@ namespace MinecraftClient
///
public static void Write(string text)
{
- if (!basicIO)
+ if (!BasicIO)
{
lock (io_lock)
{
@@ -276,29 +307,48 @@ namespace MinecraftClient
}
///
- /// Write a Minecraft-Formatted string to the standard output, using §c color codes
+ /// Write a Minecraft-Like formatted string to the standard output, using §c color codes
+ /// See minecraft.gamepedia.com/Classic_server_protocol#Color_Codes for more info
///
/// String to write
/// If false, space are printed instead of newlines
- public static void WriteLineFormatted(string str, bool acceptnewlines = true)
+ ///
+ /// If false, no timestamp is prepended.
+ /// If true, "hh-mm-ss" timestamp will be prepended.
+ /// If unspecified, value is retrieved from EnableTimestamps.
+ ///
+ public static void WriteLineFormatted(string str, bool acceptnewlines = true, bool? displayTimestamp = null)
{
- if (basicIO) { Console.WriteLine(str); return; }
if (!String.IsNullOrEmpty(str))
{
- if (Settings.chatTimeStamps)
+ if (!acceptnewlines)
+ {
+ str = str.Replace('\n', ' ');
+ }
+ if (displayTimestamp == null)
+ {
+ displayTimestamp = EnableTimestamps;
+ }
+ if (displayTimestamp.Value)
{
int hour = DateTime.Now.Hour, minute = DateTime.Now.Minute, second = DateTime.Now.Second;
ConsoleIO.Write(String.Format("{0}:{1}:{2} ", hour.ToString("00"), minute.ToString("00"), second.ToString("00")));
}
- if (!acceptnewlines) { str = str.Replace('\n', ' '); }
- if (ConsoleIO.basicIO) { ConsoleIO.WriteLine(str); return; }
- string[] subs = str.Split(new char[] { '§' });
- if (subs[0].Length > 0) { ConsoleIO.Write(subs[0]); }
- for (int i = 1; i < subs.Length; i++)
+ if (BasicIO)
{
- if (subs[i].Length > 0)
+ Console.WriteLine(str);
+ return;
+ }
+ string[] parts = str.Split(new char[] { '§' });
+ if (parts[0].Length > 0)
+ {
+ ConsoleIO.Write(parts[0]);
+ }
+ for (int i = 1; i < parts.Length; i++)
+ {
+ if (parts[i].Length > 0)
{
- switch (subs[i][0])
+ switch (parts[i][0])
{
case '0': Console.ForegroundColor = ConsoleColor.Gray; break; //Should be Black but Black is non-readable on a black background
case '1': Console.ForegroundColor = ConsoleColor.DarkBlue; break;
@@ -319,32 +369,46 @@ namespace MinecraftClient
case 'r': Console.ForegroundColor = ConsoleColor.Gray; break;
}
- if (subs[i].Length > 1)
+ if (parts[i].Length > 1)
{
- ConsoleIO.Write(subs[i].Substring(1, subs[i].Length - 1));
+ ConsoleIO.Write(parts[i].Substring(1, parts[i].Length - 1));
}
}
}
Console.ForegroundColor = ConsoleColor.Gray;
- ConsoleIO.Write('\n');
}
+ ConsoleIO.Write('\n');
}
///
- /// Write a Minecraft Console Client Log line
+ /// Write a prefixed log line. Prefix is set in LogPrefix.
///
/// Text of the log line
public static void WriteLogLine(string text)
{
- WriteLineFormatted("§8[MCC] " + text);
+ WriteLineFormatted(LogPrefix + text);
}
#region Subfunctions
+
+ ///
+ /// Clear all text inside the input prompt
+ ///
private static void ClearLineAndBuffer()
{
- while (buffer2.Length > 0) { GoRight(); }
- while (buffer.Length > 0) { RemoveOneChar(); }
+ while (buffer2.Length > 0)
+ {
+ GoRight();
+ }
+ while (buffer.Length > 0)
+ {
+ RemoveOneChar();
+ }
}
+
+ ///
+ /// Remove one character on the left of the cursor in input prompt
+ ///
private static void RemoveOneChar()
{
if (buffer.Length > 0)
@@ -369,10 +433,17 @@ namespace MinecraftClient
if (buffer2.Length > 0)
{
Console.Write(buffer2 + " \b");
- for (int i = 0; i < buffer2.Length; i++) { GoBack(); }
+ for (int i = 0; i < buffer2.Length; i++)
+ {
+ GoBack();
+ }
}
}
}
+
+ ///
+ /// Move the cursor one character to the left inside the console, regardless of input prompt state
+ ///
private static void GoBack()
{
try
@@ -387,6 +458,10 @@ namespace MinecraftClient
}
catch (ArgumentOutOfRangeException) { /* Console was resized!? */ }
}
+
+ ///
+ /// Move the cursor one character to the left in input prompt, adjusting buffers accordingly
+ ///
private static void GoLeft()
{
if (buffer.Length > 0)
@@ -396,6 +471,10 @@ namespace MinecraftClient
Console.Write('\b');
}
}
+
+ ///
+ /// Move the cursor one character to the right in input prompt, adjusting buffers accordingly
+ ///
private static void GoRight()
{
if (buffer2.Length > 0)
@@ -405,16 +484,30 @@ namespace MinecraftClient
buffer2 = buffer2.Substring(1);
}
}
+
+ ///
+ /// Insert a new character in the input prompt
+ ///
+ /// New character
private static void AddChar(char c)
{
Console.Write(c);
buffer += c;
Console.Write(buffer2);
- for (int i = 0; i < buffer2.Length; i++) { GoBack(); }
+ for (int i = 0; i < buffer2.Length; i++)
+ {
+ GoBack();
+ }
}
+
#endregion
#region Clipboard management
+
+ ///
+ /// Read a string from the Windows clipboard
+ ///
+ /// String from the Windows clipboard
private static string ReadClipboard()
{
string clipdata = "";
@@ -433,17 +526,7 @@ namespace MinecraftClient
staThread.Join();
return clipdata;
}
- #endregion
- #region AutoComplete API
- ///
- /// Set an auto-completion engine for TAB autocompletion
- ///
- /// Engine implementing the IAutoComplete interface
- public static void SetAutoCompleteEngine(IAutoComplete engine)
- {
- autocomplete_engine = engine;
- }
#endregion
}
@@ -453,6 +536,11 @@ namespace MinecraftClient
///
public interface IAutoComplete
{
+ ///
+ /// Provide a list of auto-complete strings based on the provided input behing the cursor
+ ///
+ /// Text behind the cursor, e.g. "my input comm"
+ /// List of auto-complete words, e.g. ["command", "comment"]
IEnumerable AutoComplete(string BehindCursor);
}
}
diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs
index 192b645b..ea43fb49 100644
--- a/MinecraftClient/McTcpClient.cs
+++ b/MinecraftClient/McTcpClient.cs
@@ -202,7 +202,7 @@ namespace MinecraftClient
while (client.Client.Connected)
{
text = ConsoleIO.ReadLine();
- if (ConsoleIO.basicIO && text.Length > 0 && text[0] == (char)0x00)
+ if (ConsoleIO.BasicIO && text.Length > 0 && text[0] == (char)0x00)
{
//Process a request from the GUI
string[] command = text.Substring(1).Split((char)0x00);
diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs
index f59ea8e0..2950ad7a 100644
--- a/MinecraftClient/Program.cs
+++ b/MinecraftClient/Program.cs
@@ -49,10 +49,11 @@ namespace MinecraftClient
ConsoleIO.DebugReadInput();
}
- //Basic Input/Output ?
+ //Setup ConsoleIO
+ ConsoleIO.LogPrefix = "§8[MCC] ";
if (args.Length >= 1 && args[args.Length - 1] == "BasicIO")
{
- ConsoleIO.basicIO = true;
+ ConsoleIO.BasicIO = true;
args = args.Where(o => !Object.ReferenceEquals(o, args[args.Length - 1])).ToArray();
}
@@ -116,7 +117,7 @@ namespace MinecraftClient
if (Settings.Login == "")
{
- Console.Write(ConsoleIO.basicIO ? "Please type the username or email of your choice.\n" : "Login : ");
+ Console.Write(ConsoleIO.BasicIO ? "Please type the username or email of your choice.\n" : "Login : ");
Settings.Login = Console.ReadLine();
}
if (Settings.Password == "" && (Settings.SessionCaching == CacheType.None || !SessionCache.Contains(Settings.Login.ToLower())))
@@ -133,10 +134,10 @@ namespace MinecraftClient
///
private static void RequestPassword()
{
- Console.Write(ConsoleIO.basicIO ? "Please type the password for " + Settings.Login + ".\n" : "Password : ");
- Settings.Password = ConsoleIO.basicIO ? Console.ReadLine() : ConsoleIO.ReadPassword();
+ Console.Write(ConsoleIO.BasicIO ? "Please type the password for " + Settings.Login + ".\n" : "Password : ");
+ Settings.Password = ConsoleIO.BasicIO ? Console.ReadLine() : ConsoleIO.ReadPassword();
if (Settings.Password == "") { Settings.Password = "-"; }
- if (!ConsoleIO.basicIO)
+ if (!ConsoleIO.BasicIO)
{
//Hide password length
Console.CursorTop--; Console.Write("Password : <******>");
@@ -262,7 +263,6 @@ namespace MinecraftClient
}
else
{
- Console.ForegroundColor = ConsoleColor.Gray;
string failureMessage = "Minecraft Login failed : ";
switch (result)
{
@@ -366,7 +366,10 @@ namespace MinecraftClient
ConsoleIO.WriteLineFormatted("Or press Enter to exit Minecraft Console Client.");
while (command.Length > 0)
{
- if (!ConsoleIO.basicIO) { ConsoleIO.Write('>'); }
+ if (!ConsoleIO.BasicIO)
+ {
+ ConsoleIO.Write('>');
+ }
command = Console.ReadLine().Trim();
if (command.Length > 0)
{
diff --git a/MinecraftClient/Protocol/ChatParser.cs b/MinecraftClient/Protocol/ChatParser.cs
index 9d0e7d12..60d78f66 100644
--- a/MinecraftClient/Protocol/ChatParser.cs
+++ b/MinecraftClient/Protocol/ChatParser.cs
@@ -92,8 +92,7 @@ namespace MinecraftClient.Protocol
//File not found? Try downloading language file from Mojang's servers?
if (!System.IO.File.Exists(Language_File))
{
- Console.ForegroundColor = ConsoleColor.DarkGray;
- ConsoleIO.WriteLine("Downloading '" + Settings.Language + ".lang' from Mojang servers...");
+ ConsoleIO.WriteLineFormatted("§8Downloading '" + Settings.Language + ".lang' from Mojang servers...");
try
{
string assets_index = DownloadString(Settings.TranslationsFile_Website_Index);
@@ -101,13 +100,12 @@ namespace MinecraftClient.Protocol
tmp = tmp[1].Split(new string[] { "hash\": \"" }, StringSplitOptions.None);
string hash = tmp[1].Split('"')[0]; //Translations file identifier on Mojang's servers
System.IO.File.WriteAllText(Language_File, DownloadString(Settings.TranslationsFile_Website_Download + '/' + hash.Substring(0, 2) + '/' + hash));
- ConsoleIO.WriteLine("Done. File saved as '" + Language_File + '\'');
+ ConsoleIO.WriteLineFormatted("§8Done. File saved as '" + Language_File + '\'');
}
catch
{
- ConsoleIO.WriteLine("Failed to download the file.");
+ ConsoleIO.WriteLineFormatted("§8Failed to download the file.");
}
- Console.ForegroundColor = ConsoleColor.Gray;
}
//Download Failed? Defaulting to en_GB.lang if the game is installed
diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs
index fcd2087f..f066f436 100644
--- a/MinecraftClient/Settings.cs
+++ b/MinecraftClient/Settings.cs
@@ -79,7 +79,6 @@ namespace MinecraftClient
public static List Bots_Owners = new List();
public static TimeSpan botMessageDelay = TimeSpan.FromSeconds(2);
public static string Language = "en_GB";
- public static bool chatTimeStamps = false;
public static bool interactiveMode = true;
public static char internalCmdChar = '/';
public static bool playerHeadAsIcon = false;
@@ -214,7 +213,7 @@ namespace MinecraftClient
case "singlecommand": SingleCommand = argValue; break;
case "language": Language = argValue; break;
case "consoletitle": ConsoleTitle = argValue; break;
- case "timestamps": chatTimeStamps = str2bool(argValue); break;
+ case "timestamps": ConsoleIO.EnableTimestamps = str2bool(argValue); break;
case "exitonfailure": interactiveMode = !str2bool(argValue); break;
case "playerheadicon": playerHeadAsIcon = str2bool(argValue); break;
case "chatbotlogfile": chatbotLogFile = argValue; break;