예제 #1
0
        internal static void LoadInternalCommands()
        {
            CFormat.WriteLine("[CommandManager] Loading internal commands...");

            List <Type> foundInternalLibraries = ((IEnumerable <Type>)Assembly.GetExecutingAssembly().GetTypes()).Where(t =>
            {
                if (t.IsClass && t.GetCustomAttributes().Where(a => a.GetType() == typeof(MMasterLibrary)).Any())
                {
                    return(t.Namespace == _InternalNamespace);
                }
                return(false);
            }).ToList();

            if (foundInternalLibraries.Count() == 0)
            {
                CFormat.WriteLine(ConsoleColor.Red, "[CommandManager] CRITICAL ISSUE: No internal commands loaded.",
                                  "[CommandManager] Please report bug on GitHub at MMaster-Command-Prompt page.");
                CFormat.JumpLine();
                return;
            }

            foreach (Type library in foundInternalLibraries)
            {
                string libraryCallName = library.GetCustomAttribute <MMasterLibrary>().CallName;
                if (String.IsNullOrEmpty(libraryCallName))
                {
                    libraryCallName = library.Name;
                }

                IEnumerable <MethodInfo> methodInfos = library.GetMethods(BindingFlags.Static | BindingFlags.Public)
                                                       .Where <MethodInfo>((Func <MethodInfo, bool>)(m => ((IEnumerable <object>)m.GetCustomAttributes(false))
                                                                                                     .Where <object>((Func <object, bool>)(a => a.GetType().Name.Contains(typeof(MMasterCommand).Name))).Any()));

                Dictionary <string, MethodInfo> dictionary = new Dictionary <string, MethodInfo>();

                foreach (MethodInfo methodInfo in methodInfos)
                {
                    string commandCallName = methodInfo.GetCustomAttribute <MMasterCommand>().CallName;
                    if (String.IsNullOrEmpty(commandCallName))
                    {
                        commandCallName = methodInfo.Name;
                    }

                    if (dictionary.ContainsKey(commandCallName))
                    {
                        CFormat.WriteLine(string.Format("[CommandManager] Could not load command named \"{0}.{1}\" because one already exists.", libraryCallName, commandCallName), ConsoleColor.Red);
                    }
                    else
                    {
                        dictionary.Add(commandCallName, methodInfo);
                    }
                }

                InternalLibraryCallNames.Add(libraryCallName, library);
                InternalLibraries.Add(library, dictionary);
            }

            CFormat.WriteLine("[CommandManager] Internal commands loaded.");
            CFormat.JumpLine();
        }
예제 #2
0
        private static void Loaddependencies(FileID fileId, string fileCode, int degree = 0)
        {
            foreach (Match match in new Regex("// DEP \\\"(.+)\\\"").Matches(fileCode))
            {
                string result = Path.GetFullPath(match.Groups[1].Value);

                FileAttributes fileAttributes = File.GetAttributes(result);

                if (fileAttributes.HasFlag(FileAttributes.Directory) && Directory.Exists(result))
                {
                    CFormat.WriteLine(string.Format("[CommandManager]    {0}Found dependency in \"{1}\": loading \"{2}\" directory.", CFormat.Indent(degree * 3), fileId.Name, result), ConsoleColor.Cyan);
                    LoadDirectory(result, true, true, true, degree + 1);
                }
                else if (File.Exists(result))
                {
                    CFormat.WriteLine(string.Format("[CommandManager]    {0}Found dependency in \"{1}\": loading \"{2}\" file.", CFormat.Indent(degree * 3), fileId.Name, result), ConsoleColor.Cyan);

                    if (Path.GetExtension(result) != _ExternalExtension)
                    {
                        CFormat.WriteLine(string.Format("[CommandManager]       {0}The file dependency \"{1}\" is not a (*.cs) file and was not loaded.", CFormat.Indent(degree * 3), result), ConsoleColor.Red);
                        return;
                    }

                    LoadFile(result, true, true, degree + 1);
                }
                else
                {
                    CFormat.WriteLine(string.Format("[CommandManager]    The dependency \"{0}\" found in \"{1}\" does not exist.", result, fileId.Name), ConsoleColor.DarkYellow);
                }
            }
        }
예제 #3
0
        public static void DrawProgressBar(
            double complete,
            double maxVal,
            int barSize,
            char progressCharacter,
            ConsoleColor primaryColor   = ConsoleColor.Green,
            ConsoleColor secondaryColor = ConsoleColor.DarkGreen)
        {
            Console.CursorVisible = false;
            int    cursorLeft = Console.CursorLeft;
            double num1       = complete / maxVal;
            int    num2       = (int)Math.Floor(num1 / (1.0 / (double)barSize));
            string empty1     = string.Empty;
            string empty2     = string.Empty;

            for (int index = 0; index < num2; ++index)
            {
                empty1 += progressCharacter.ToString();
            }
            for (int index = 0; index < barSize - num2; ++index)
            {
                empty2 += progressCharacter.ToString();
            }
            CFormat.Write(empty1, primaryColor);
            CFormat.Write(empty2, secondaryColor);
            CFormat.Write(string.Format(" {0}%", (num1 * 100.0).ToString("N2")), primaryColor);
            Console.ResetColor();
            Console.CursorVisible = true;
            Console.CursorLeft    = cursorLeft;
        }
예제 #4
0
        private static void Execute(string userInput)
        {
            try
            {
                CParsedInput parsedInput = new CParsedInput(userInput);

                parsedInput.CommandMethodInfo.Invoke(null, parsedInput.Parameters);
            }
            catch (WrongCallFormatException)
            {
                CFormat.WriteLine("Wrong call format.", "The call should be as it follows: <Library>.<Command> [arg1] [arg2] [etc.]");
            }
            catch (LibraryNotExistingException)
            {
                CFormat.WriteLine("This library does not exist.");
            }
            catch (CommandNotExistingException)
            {
                CFormat.WriteLine("This command does not exist.");
            }
            catch (MissingArgumentException ex)
            {
                CFormat.WriteLine("Missing required argument.", CFormat.GetArgsFormat(ex.ParsedInput.FullCallName, ex.ParsedInput.CommandMethodInfo.GetParameters()));
            }
            catch (ArgumentCoerceException ex)
            {
                CFormat.WriteLine(string.Format("The argument '{0}' cannot be parsed to type '{1}'", ex.ArgumentName, ex.ArgumentTargetType));
            }
            catch (Exception ex)
            {
                CFormat.WriteLine(ex.Message);
            }
        }
예제 #5
0
 private static void Main(string[] args)
 {
     Console.Title = Program.appName;
     CFormat.WriteLine(Program.bootMessage, ConsoleColor.Cyan);
     CFormat.JumpLine();
     CommandManager.LoadInternalCommands();
     CommandManager.LoadExternalCommands(true);
     CFormat.JumpLine();
     CFormat.WriteLine("Type 'List' to get the list of available commands.", ConsoleColor.Gray);
     Program.Run();
 }
예제 #6
0
        internal static void LoadDirectory(string initialPath, bool subdirectories = true, bool successMessage = true, bool isdependency = false, int degree = 0)
        {
            string path  = initialPath;
            int    count = ExternalLibraries.Count;

            try
            {
                if (string.IsNullOrEmpty(path))
                {
                    path = _externalDirectory;
                }

                if (Directory.Exists(path))
                {
                    foreach (string file in Directory.GetFiles(path, "*.cs",
                                                               subdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                    {
                        LoadFile(file, successMessage, isdependency, degree);
                    }

                    if (ExternalLibraries.Count > count)
                    {
                        if (successMessage && !isdependency)
                        {
                            if (string.IsNullOrEmpty(initialPath))
                            {
                                CFormat.WriteLine(string.Format("[CommandManager] {0}External commands loaded.", CFormat.Indent(degree * 3)));
                            }
                            else
                            {
                                CFormat.WriteLine(string.Format("[CommandManager] {0}External commands in \"{1}\" directory successfully loaded!", CFormat.Indent(degree * 3), path));
                            }
                        }
                    }
                    else
                    if (!isdependency)
                    {
                        CFormat.WriteLine(string.Format("[CommandManager] {0}No external commands loaded.", CFormat.Indent(degree * 3)));
                    }
                }
                else
                {
                    CFormat.WriteLine(string.Format("[CommandManager] {0}Could not find directory named \"{1}\".", CFormat.Indent(degree * 3), Path.GetDirectoryName(path)), ConsoleColor.Red);
                }
            }
            catch (Exception ex)
            {
                CFormat.WriteLine(string.Format("[CommandManager] {0}Could not load directory named \"{1}\": {2}", CFormat.Indent(degree * 3), Path.GetDirectoryName(path), ex.Message), ConsoleColor.Red);
            }
        }
예제 #7
0
        private static void Run()
        {
            while (true)
            {
                string userInput;
                do
                {
                    CFormat.JumpLine();
                    userInput = CInput.ReadFromConsole("", ConsoleInputType.String, false, -1, char.MinValue).ToString();
                }while (string.IsNullOrWhiteSpace(userInput));

                Execute(userInput);
            }
        }
예제 #8
0
 private static void ReferenceAssemblies(ref CompilerParameters parameters, string fileCode, string fileName, bool isdependency = false, int degree = 0)
 {
     foreach (Match match in new Regex("// REF \\\"(.+)\\\"").Matches(fileCode))
     {
         try
         {
             parameters.ReferencedAssemblies.Add(match.Groups[1].Value);
             CFormat.WriteLine(string.Format("[CommandManager]    {0}Found referenced assembly in \"{1}\": \"{2}\"", CFormat.Indent(degree * 3), fileName, match.Groups[1].Value), ConsoleColor.Gray);
         }
         catch (Exception ex)
         {
             CFormat.WriteLine(string.Format("[CommandManager]    {0}Could not load referenced assembly in {1}: \"{2}\". Details: {3}", CFormat.Indent(degree * 3), fileName, match.Captures[3].Value, ex.Message), ConsoleColor.Red);
         }
     }
 }
예제 #9
0
        public static int UserPickInt(int maxNumber)
        {
            object obj = CInput.ReadFromConsole("Enter a number between 0 and " + maxNumber + ": ", ConsoleInputType.Int, true, maxNumber.ToString().Length, char.MinValue);

            if (obj == null)
            {
                CFormat.WriteLine("[Canceled]", ConsoleColor.DarkYellow);
                return(-1);
            }
            if ((int)obj >= 0 && (int)obj <= maxNumber)
            {
                return((int)obj);
            }
            CInput.UserPickInt(maxNumber);
            return(-1);
        }
예제 #10
0
 internal static void UnloadFile(int id)
 {
     try
     {
         foreach (string libraryCallName in LoadedFileIDs[id].LibraryCallNames)
         {
             ExternalLibraries.Remove(ExternalLibraryCallNames[libraryCallName]);
             ExternalLibraryCallNames.Remove(libraryCallName);
         }
         LoadedFileIDs.RemoveAll(x => x.ID == id);
         CFormat.WriteLine("[ComandManager] File unloaded successfully!", ConsoleColor.Green);
     }
     catch (Exception ex)
     {
         CFormat.WriteLine("[CommandManager] Could not unload file \"" + CommandManager.LoadedFileIDs[id].Path + "\". Details: " + ex.Message, ConsoleColor.Red);
     }
 }
예제 #11
0
        internal static void LoadFile(string rawPath, bool successMessage = true, bool isdependency = false, int degree = 0)
        {
            string path = Path.GetFullPath(rawPath);

            FileID fileId = new FileID(CommandManager.LoadedFileIDs.Count + (isdependency ? 1:0), path, isdependency);

            try
            {
                if (LoadedFileIDs.Any(x => x.Path == path && !x.LoadedAsdependency))
                {
                    CFormat.WriteLine(string.Format("[CommandManager] {0}Could not load file named \"{1}\" because it has already been loaded.", CFormat.Indent(degree * 3), fileId.Name), ConsoleColor.Red);
                    return;
                }
                else if (LoadedFileIDs.Any(x => x.Path == path && x.LoadedAsdependency))
                {
                    return;
                }
                else
                {
                    CFormat.WriteLine(string.Format("[CommandManager] {0}Loading \"{1}\"...", CFormat.Indent(degree * 3), fileId.Name));

                    string fileCode = "";
                    using (StreamReader streamReader = new StreamReader(path))
                        fileCode = streamReader.ReadToEnd();

                    CompilerParameters parameters = new CompilerParameters()
                    {
                        GenerateInMemory = true
                    };

                    parameters.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location);
                    ReferenceAssemblies(ref parameters, fileCode, fileId.Name, isdependency, degree);
                    Loaddependencies(fileId, fileCode, degree);
                    CompilerResults compilerResults = _provider.CompileAssemblyFromSource(parameters, fileCode);

                    if ((uint)compilerResults.Errors.Count > 0U)
                    {
                        CFormat.WriteLine(string.Format("[CommandManager] {0}Could not load file named \"{1}\":", CFormat.Indent(degree * 3), fileId.Name), ConsoleColor.Red);
                        foreach (CompilerError error in compilerResults.Errors)
                        {
                            CFormat.WriteLine(string.Format("[CommandManager] {0}({1},{2}): error {3}: {4}", CFormat.Indent(degree * 3), error.Line, error.Column, error.ErrorNumber, error.ErrorText), ConsoleColor.Red);
                        }
                    }
                    else
                    {
                        List <Type> foundExternalLibraries = compilerResults.CompiledAssembly.GetTypes()
                                                             .Where(t => t.IsClass && t.GetCustomAttributes().Where(a => a.GetType() == typeof(MMasterLibrary)).Any()).ToList();

                        if (foundExternalLibraries.Count == 0)
                        {
                            CFormat.WriteLine(string.Format("[CommandManager]    {0}\"{1}\" does not contain any library.", CFormat.Indent(degree * 3), fileId.Name), ConsoleColor.DarkYellow);
                            return;
                        }

                        foreach (Type library in foundExternalLibraries)
                        {
                            string libraryCallName = library.GetCustomAttribute <MMasterLibrary>().CallName;
                            if (String.IsNullOrEmpty(libraryCallName))
                            {
                                libraryCallName = library.Name;
                            }

                            if (InternalLibraryCallNames.ContainsKey(libraryCallName) || ExternalLibraryCallNames.ContainsKey(libraryCallName))
                            {
                                CFormat.WriteLine(string.Format("[CommandManager]    {0}Could not load library named \"{1}\" in \"{2}\" because one with the same name already exists.", CFormat.Indent(degree * 3), libraryCallName, fileId.Name), ConsoleColor.DarkYellow);
                                continue;
                            }

                            IEnumerable <MethodInfo> methodInfos = library.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                                                                   .Where <MethodInfo>((Func <MethodInfo, bool>)(m => ((IEnumerable <object>)m.GetCustomAttributes(false))
                                                                                                                 .Where <object>((Func <object, bool>)(a => a.GetType().Name.Contains(typeof(MMasterCommand).Name))).Any()));

                            Dictionary <string, MethodInfo> dictionary = new Dictionary <string, MethodInfo>();

                            foreach (MethodInfo methodInfo in methodInfos)
                            {
                                string commandCallName = methodInfo.GetCustomAttribute <MMasterCommand>().CallName;
                                if (String.IsNullOrEmpty(commandCallName))
                                {
                                    commandCallName = methodInfo.Name;
                                }

                                if (dictionary.ContainsKey(commandCallName))
                                {
                                    CFormat.WriteLine(string.Format("[CommandManager]    {0}Could not load command named \"{1}.{2}\" in \"{3}\" because one with the same name already exists.", CFormat.Indent(degree * 3), libraryCallName, commandCallName, fileId.Name), ConsoleColor.DarkYellow);
                                }
                                else
                                {
                                    dictionary.Add(commandCallName, methodInfo);
                                }
                            }

                            ExternalLibraryCallNames.Add(libraryCallName, library);
                            ExternalLibraries.Add(library, dictionary);
                            fileId.LibraryCallNames.Add(libraryCallName);
                        }

                        LoadedFileIDs.Add(fileId);
                        if (!successMessage)
                        {
                            return;
                        }
                        CFormat.WriteLine(string.Format("[CommandManager] {0}Loaded \"{1}\" successfully!", CFormat.Indent(degree * 3), fileId.Name), isdependency ? ConsoleColor.Cyan : ConsoleColor.Green);
                    }
                }
            }
            catch (Exception ex)
            {
                CFormat.WriteLine(string.Format("[CommandManager] {0}Could not load file named \"{1}\": {2}", CFormat.Indent(degree * 3), fileId.Name, ex.Message), ConsoleColor.Red);
            }
        }
예제 #12
0
 internal static void LoadExternalCommands(bool successMessage = false)
 {
     CFormat.WriteLine("[CommandManager] Loading external commands in application's directory (and sub-directories)...");
     LoadDirectory("", true, successMessage);
     LoadedFileIDs = LoadedFileIDs.OrderBy(x => x.ID).ToList();
 }
예제 #13
0
 public static void JumpLine()
 {
     CFormat.WriteLine("");
 }
예제 #14
0
        internal CParsedInput(string input, bool ignoreArguments = false)
        {
            string[] splitInput = Regex.Split(input, "(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*) (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

            Arguments = new List <string>();

            this.RawCall = splitInput[0];

            string[] splitCall = splitInput[0].Split('.');

            // LIBRARY & COMMAND
            if (splitCall.Length == 1) // We assume here that if there is no dot, then this implies that the target library is Default.
            {
                Library = typeof(Default);

                if (CommandManager.InternalLibraries[Library].Keys.Any(x => x.ToLower() == splitCall[0].ToLower()))
                {
                    CommandCallName   = CommandManager.InternalLibraries[Library].Keys.FirstOrDefault(x => x.ToLower() == splitCall[0].ToLower());
                    CommandMethodInfo = CommandManager.InternalLibraries[Library][CommandCallName];
                }
                else
                {
                    throw new CommandNotExistingException();
                }
            }
            else if (splitCall.Length == 2) // Most common scenarios
            {
                if (CommandManager.InternalLibraryCallNames.ContainsKey(splitCall[0]))
                {
                    Library = CommandManager.InternalLibraryCallNames[splitCall[0]];

                    if (CommandManager.InternalLibraries[Library].Keys.Any(x => x.ToLower() == splitCall[1].ToLower()))
                    {
                        CommandCallName   = CommandManager.InternalLibraries[Library].Keys.FirstOrDefault(x => x.ToLower() == splitCall[1].ToLower());
                        CommandMethodInfo = CommandManager.InternalLibraries[Library][CommandCallName];
                    }
                    else
                    {
                        throw new CommandNotExistingException();
                    }
                }
                else if (CommandManager.ExternalLibraryCallNames.ContainsKey(splitCall[0]))
                {
                    Library = CommandManager.ExternalLibraryCallNames[splitCall[0]];

                    if (CommandManager.ExternalLibraries[Library].Keys.Any(x => x.ToLower() == splitCall[1].ToLower()))
                    {
                        CommandCallName   = CommandManager.ExternalLibraries[Library].Keys.FirstOrDefault(x => x.ToLower() == splitCall[1].ToLower());
                        CommandMethodInfo = CommandManager.ExternalLibraries[Library][CommandCallName];
                    }
                    else
                    {
                        throw new CommandNotExistingException();
                    }
                }
                else
                {
                    throw new LibraryNotExistingException();
                }
            }
            else
            {
                throw new WrongCallFormatException();
            }



            if (ignoreArguments)
            {
                return;
            }



            // PARSE ARGS
            for (int index = 1; index < splitInput.Length; ++index)
            {
                string rawArg      = splitInput[index];
                string computedArg = rawArg;
                Match  match       = new Regex("\"(.*?)\"", RegexOptions.Singleline).Match(rawArg);
                if (match.Captures.Count > 0)
                {
                    computedArg = new Regex("[^\"]*[^\"]").Match(match.Captures[0].Value).Captures[0].Value;
                }
                this.Arguments.Add(computedArg);
            }

            // COERCE ARGS
            IEnumerable <ParameterInfo> parameterInfos = CommandMethodInfo.GetParameters().ToList();
            List <object> objectList = new List <object>(); // Collecting args as objects

            IEnumerable <ParameterInfo> parameterInfosNecessary = parameterInfos.Where(p => !p.IsOptional);
            IEnumerable <ParameterInfo> parameterInfosOptional  = parameterInfos.Where(p => p.IsOptional);

            if (parameterInfosNecessary.Count() > Arguments.Count())
            {
                throw new MissingArgumentException(this);
            }
            else
            {
                if (parameterInfos.Count() > 0)
                {
                    foreach (ParameterInfo PI in parameterInfos)
                    {
                        objectList.Add(PI.DefaultValue);
                    }

                    for (int index = 0; index < parameterInfos.Count(); ++index)
                    {
                        ParameterInfo PI            = parameterInfos.ElementAt(index);
                        Type          parameterType = PI.ParameterType;

                        try // The following instruction can fail (in case of optional args) so its accessibility is tested before.
                        {
                            Arguments.ElementAt(index);
                        }
                        catch
                        {
                            continue;
                        }

                        object obj = CFormat.CoerceArgument(parameterType, Arguments.ElementAt(index));
                        objectList.RemoveAt(index);
                        objectList.Insert(index, obj);
                    }

                    // EXPORT PARAMETERS to an array
                    if (objectList.Count > 0)
                    {
                        Parameters = objectList.ToArray();
                    }
                }
            }
        }
예제 #15
0
        public static ConsoleAnswer UserChoice(ConsoleAnswerType type, bool canEscape = false)
        {
            switch (type)
            {
            case ConsoleAnswerType.YesNo:
                object object1 = CInput.ReadFromConsole("(YES / NO): ", ConsoleInputType.String, canEscape, 3, char.MinValue);
                if (object1 == null)
                {
                    CFormat.WriteLine("[Canceled]", ConsoleColor.DarkYellow);
                    return(ConsoleAnswer.Escaped);
                }
                string str1 = object1.ToString().ToLower();
                if (str1 == "y" || str1 == "yes")
                {
                    return(ConsoleAnswer.Yes);
                }
                if (str1 == "n" || str1 == "no")
                {
                    return(ConsoleAnswer.No);
                }
                return(CInput.UserChoice(type));


            case ConsoleAnswerType.YesNoCancel:
                object object2 = CInput.ReadFromConsole("(YES / NO / CANCEL): ", ConsoleInputType.String, canEscape, 6, char.MinValue);
                if (object2 == null)
                {
                    CFormat.WriteLine("[Canceled]", ConsoleColor.DarkYellow);
                    return(ConsoleAnswer.Escaped);
                }
                string str2 = object2.ToString().ToLower();
                if (str2 == "y" || str2 == "yes")
                {
                    return(ConsoleAnswer.Yes);
                }
                if (str2 == "n" || str2 == "no")
                {
                    return(ConsoleAnswer.No);
                }
                if (str2 == "c" || str2 == "cancel")
                {
                    return(ConsoleAnswer.Cancel);
                }
                return(CInput.UserChoice(type));

            case ConsoleAnswerType.TrueFalse:
                object object3 = CInput.ReadFromConsole("(TRUE / FALSE): ", ConsoleInputType.String, canEscape, 5, char.MinValue);
                if (object3 == null)
                {
                    CFormat.WriteLine("[Canceled]", ConsoleColor.DarkYellow);
                    return(ConsoleAnswer.Escaped);
                }
                string str3 = object3.ToString().ToLower();
                if (str3 == "t" || str3 == "true")
                {
                    return(ConsoleAnswer.Yes);
                }
                if (str3 == "f" || str3 == "false")
                {
                    return(ConsoleAnswer.No);
                }
                return(CInput.UserChoice(type));

            default:
                CFormat.WriteLine("[CInput] ERROR: Could not get user choice, specifed answer type does not exist.", ConsoleColor.Red);
                return(ConsoleAnswer.Undefined);
            }
        }
예제 #16
0
        public static object ReadFromConsole(
            string promptMessage       = "",
            ConsoleInputType inputType = ConsoleInputType.String,
            bool canEscape             = false,
            int maxChars  = -1,
            char charMask = '\0')
        {
            ConsoleColor foregroundColor = Console.ForegroundColor;
            bool         maskFlag        = charMask > char.MinValue;
            bool         runFlag         = true;

            promptMessage           = promptMessage == "" ? "MMaster> " : promptMessage;
            cursorPos               = 0;
            historyIndex            = 0;
            tabAllowed              = true;
            _readBuffer             = "";
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write(promptMessage);

            while (runFlag)
            {
                ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(true);


                // READ BUFFER
                if (consoleKeyInfo.Key == ConsoleKey.Enter)
                {
                    ValidateHistory();
                    if (!String.IsNullOrEmpty(_readBuffer))
                    {
                        AddToHistory(_readBuffer);
                    }

                    Console.ForegroundColor = foregroundColor;
                    CFormat.JumpLine();

                    switch (inputType)
                    {
                    case ConsoleInputType.String:
                        return(_readBuffer);

                    case ConsoleInputType.Int:
                        if (String.IsNullOrEmpty(_readBuffer))
                        {
                            return(null);
                        }
                        return(int.Parse(_readBuffer));

                    case ConsoleInputType.Double:
                        if (String.IsNullOrEmpty(_readBuffer))
                        {
                            return(null);
                        }
                        return(double.Parse(_readBuffer.Replace(".", ",")));
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.Backspace)
                {
                    ValidateHistory();
                    if (cursorPos > 0)
                    {
                        if (cursorPos != _readBuffer.Length)
                        {
                            string str2 = _readBuffer.Substring(0, cursorPos - 1);
                            string str3 = _readBuffer.Substring(cursorPos, _readBuffer.Length - cursorPos);
                            _readBuffer = str2 + str3;
                            MoveCursorBack();
                            UserWrite(str3 + " ");
                            for (int index = 0; index < str3.Length + 1; ++index)
                            {
                                MoveCursorBack();
                            }
                        }
                        else
                        {
                            _readBuffer = _readBuffer.Substring(0, _readBuffer.Length - 1);
                            MoveCursorBack();
                            UserWrite(" ");
                            MoveCursorBack();
                        }
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.Delete)
                {
                    ValidateHistory();
                    if (cursorPos < _readBuffer.Length)
                    {
                        string str2 = _readBuffer.Substring(0, cursorPos);
                        string str3 = _readBuffer.Substring(cursorPos + 1, _readBuffer.Length - cursorPos - 1);
                        _readBuffer = str2 + str3;
                        UserWrite(str3 + " ");
                        for (int index = 0; index < str3.Length + 1; ++index)
                        {
                            MoveCursorBack();
                        }
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.Home)
                {
                    for (int cursorPos = CInput.cursorPos; cursorPos > 0; --cursorPos)
                    {
                        MoveCursorBack();
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.End)
                {
                    for (int cursorPos = CInput.cursorPos; cursorPos < _readBuffer.Length; ++cursorPos)
                    {
                        MoveCursorAhead();
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.Escape)
                {
                    if (canEscape)
                    {
                        return(null);
                    }
                }
                else if (consoleKeyInfo.Key == ConsoleKey.Insert)
                {
                    insertMode         = !insertMode;
                    Console.CursorSize = !insertMode ? 1 : 100;
                }
                else if (consoleKeyInfo.Key != ConsoleKey.Spacebar && consoleKeyInfo.KeyChar == char.MinValue)
                {
                    if (consoleKeyInfo.Key == ConsoleKey.RightArrow && cursorPos < _readBuffer.Length)
                    {
                        MoveCursorAhead();
                    }
                    else if (consoleKeyInfo.Key == ConsoleKey.LeftArrow && cursorPos > 0)
                    {
                        MoveCursorBack();
                    }
                    else if (consoleKeyInfo.Key == ConsoleKey.UpArrow)
                    {
                        OlderHistory();
                    }
                    else if (consoleKeyInfo.Key == ConsoleKey.DownArrow)
                    {
                        NewerHistory();
                    }
                }
                // Tab auto-completition
                else if (consoleKeyInfo.Key == ConsoleKey.Tab)
                {
                    if (String.IsNullOrEmpty(_readBuffer) || !tabAllowed || _readBuffer.Contains(" "))
                    {
                        continue;
                    }

                    if (!_readBuffer.Contains(".")) // If looking for a library OR default command
                    {
                        //Try internal libraries first
                        string result = CommandManager.InternalLibraryCallNames.Keys.FirstOrDefault(x => x.ToLower().StartsWith(_readBuffer.ToLower()));
                        //Then try external libraries
                        if (result == null)
                        {
                            result = CommandManager.ExternalLibraryCallNames.Keys.FirstOrDefault(x => x.ToLower().StartsWith(_readBuffer.ToLower()));
                        }
                        // If still null, no result at all in libraries
                        if (result != null)
                        {
                            for (int i = 0; i < _readBuffer.Length; i++)
                            {
                                MoveCursorBack();
                            }
                            UserWrite(result);
                            _readBuffer = result;
                        }

                        // Then trying in Default library, the only one that can be called without library.
                        result = CommandManager.InternalLibraries[typeof(Default)].Keys.FirstOrDefault(x => x.ToLower().StartsWith(_readBuffer.ToLower()));

                        if (result == null)
                        {
                            continue;
                        }
                        else
                        {
                            for (int i = 0; i < _readBuffer.Length; i++)
                            {
                                MoveCursorBack();
                            }
                            UserWrite(result);
                            _readBuffer = result;
                        }
                    }
                    else // If the buffer contains a point.
                    {
                        // PARSE LIBRARY
                        Type   library           = CParsedInput.ParseLibrary(_readBuffer.Split('.')[0]);
                        string commandInputLower = _readBuffer.Split('.')[1].ToLower();

                        if (library == null || commandInputLower == "")
                        {
                            continue;
                        }

                        // Try internal libraries
                        string result = null;
                        if (CommandManager.InternalLibraries.ContainsKey(library))
                        {
                            result = CommandManager.InternalLibraries[library].Keys.FirstOrDefault(x => x.ToLower().StartsWith(commandInputLower));
                        }
                        // Then try external
                        else
                        {
                            result = CommandManager.ExternalLibraries[library].Keys.FirstOrDefault(x => x.ToLower().StartsWith(commandInputLower));
                        }

                        // If result found
                        if (result != null)
                        {
                            for (int i = 0; i < _readBuffer.Length; i++)
                            {
                                MoveCursorBack();
                            }

                            string libraryCallName = library.GetCustomAttribute <MMasterLibrary>().CallName;
                            UserWrite(libraryCallName + "." + result);
                            _readBuffer = libraryCallName + "." + result;
                        }
                    }

                    continue;
                }
                else
                {
                    CInput.ValidateHistory();
                    if (maxChars <= 0 || CInput._readBuffer.Length < maxChars)
                    {
                        char keyChar;
                        switch (inputType)
                        {
                        case ConsoleInputType.Int:
                            keyChar = consoleKeyInfo.KeyChar;
                            int num1;
                            if (!int.TryParse(keyChar.ToString(), out _))
                            {
                                keyChar = consoleKeyInfo.KeyChar;
                                if (!(keyChar.ToString() != "-"))
                                {
                                    keyChar = consoleKeyInfo.KeyChar;
                                    num1    = !(keyChar.ToString() == "-") ? 0 : ((uint)CInput._readBuffer.Length > 0U ? 1 : 0);
                                }
                                else
                                {
                                    num1 = 1;
                                }
                            }
                            else
                            {
                                num1 = 0;
                            }
                            if (num1 == 0)
                            {
                                break;
                            }
                            continue;

                        case ConsoleInputType.Double:
                            keyChar = consoleKeyInfo.KeyChar;
                            int num2;
                            if (!int.TryParse(keyChar.ToString(), out _))
                            {
                                keyChar = consoleKeyInfo.KeyChar;
                                if (!(keyChar.ToString() != "."))
                                {
                                    keyChar = consoleKeyInfo.KeyChar;
                                    if (!(keyChar.ToString() == ".") || !CInput._readBuffer.Contains("."))
                                    {
                                        goto label_54;
                                    }
                                }
                                keyChar = consoleKeyInfo.KeyChar;
                                if (!(keyChar.ToString() != "-"))
                                {
                                    keyChar = consoleKeyInfo.KeyChar;
                                    num2    = !(keyChar.ToString() == "-") ? 0 : (CInput._readBuffer.Length != 0 ? 1 : (CInput._readBuffer.Contains(".") ? 1 : 0));
                                    goto label_55;
                                }
                                else
                                {
                                    num2 = 1;
                                    goto label_55;
                                }
                            }
label_54:
                            num2 = 0;
label_55:
                            if (num2 == 0)
                            {
                                break;
                            }
                            continue;
                        }
                        if (CInput.cursorPos != CInput._readBuffer.Length && !CInput.insertMode) // If in the word, insert mode off
                        {
                            string str2 = CInput._readBuffer.Substring(0, CInput.cursorPos);
                            keyChar = consoleKeyInfo.KeyChar;
                            string str3 = keyChar.ToString();
                            string str4 = CInput._readBuffer.Substring(CInput.cursorPos, CInput._readBuffer.Length - CInput.cursorPos);
                            CInput._readBuffer = str2 + str3 + str4;
                        }
                        else if (CInput.cursorPos != CInput._readBuffer.Length && CInput.insertMode) // If in the word, insert mode on
                        {
                            string str2 = CInput._readBuffer.Substring(0, CInput.cursorPos);
                            keyChar = consoleKeyInfo.KeyChar;
                            string str3 = keyChar.ToString();
                            string str4 = CInput._readBuffer.Substring(CInput.cursorPos + 1, CInput._readBuffer.Length - CInput.cursorPos - 1);
                            CInput._readBuffer = str2 + str3 + str4;
                        }
                        else
                        {
                            string readBuffer = CInput._readBuffer;
                            keyChar = consoleKeyInfo.KeyChar;
                            string str2 = keyChar.ToString();
                            CInput._readBuffer = readBuffer + str2;
                        }


                        // PRINT TO SCREEN
                        if (maskFlag)
                        {
                            CInput.UserWrite(charMask.ToString());
                        }
                        else
                        {
                            keyChar = consoleKeyInfo.KeyChar;
                            CInput.UserWrite(keyChar.ToString());
                            if (CInput.cursorPos != CInput._readBuffer.Length && !CInput.insertMode)
                            {
                                string s = CInput._readBuffer.Substring(CInput.cursorPos, CInput._readBuffer.Length - CInput.cursorPos);
                                CInput.UserWrite(s);
                                for (int index = 0; index < s.Length; ++index)
                                {
                                    CInput.MoveCursorBack();
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }