Beispiel #1
0
        /// <summary>
        /// The REPL Loop. <br>Loops until an external shutdown of the shell as been triggered by the assistant core program.</br>
        /// </summary>
        /// <returns></returns>
        private static async Task ReplAsync()
        {
            if (!InitCompleted)
            {
                return;
            }

            await LoopSync.WaitAsync().ConfigureAwait(false);

            try {
                Logger.Info("Command Shell has been loaded!");
                bool isDisplayed = false;

                do
                {
                    if (PauseShell)
                    {
                        if (!isDisplayed)
                        {
                            Logger.Trace("Shell is in 'Paused' state.");
                            isDisplayed = true;
                        }

                        await Task.Delay(1).ConfigureAwait(false);

                        continue;
                    }

                    Logger.Trace("Shell is in 'Running' state.");
                    Console.WriteLine();
                    ShellIO.Info("Type in the command! Use 'help' / 'h' for help regarding the available commands.");
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.Write($"#~{Assembly.GetExecutingAssembly().GetName().Name}/$ >> ");
                    Console.ResetColor();
                    string command = Console.ReadLine();

                    if (string.IsNullOrEmpty(command) || string.IsNullOrWhiteSpace(command))
                    {
                        ShellIO.Error("Invalid command.");
                        continue;
                    }

                    await ExecuteCommandAsync(command).ConfigureAwait(false);

                    Console.WriteLine("Completed!");
                    Pause();
                } while (!ShutdownShell);
            }
            catch (Exception e) {
                Logger.Exception(e);
                Logger.Error("Fatal exception has occurred internally. Shell cannot continue.");
                return;
            }
            finally {
                LoopSync.Release();
                Logger.Info("Shell has been shutdown.");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Executes the received command by first parsing it then executing with the parsed values.
        /// </summary>
        /// <param name="command">The command<see cref="string"/></param>
        /// <returns>The <see cref="bool"/></returns>
        private static async Task <bool> ExecuteCommandAsync(string?command)
        {
            if (!InitCompleted)
            {
                Logger.Warn("Shell isn't initiated properly.");
                ShellIO.Error("Shell is offline!");
                return(false);
            }

            if (string.IsNullOrEmpty(command))
            {
                Logger.Trace("Command is null.");
                ShellIO.Error("Command empty or invalid.");
                return(false);
            }

            CurrentCommand = command;
            return(await ParseCommandAsync(command).ConfigureAwait(false));
        }
Beispiel #3
0
        /// <summary>
        /// Executes the command.
        /// Searches the command with its command key on the internal command collection.
        /// Cross checks the result command by verifying its argument count.
        /// Then executes the command.
        /// </summary>
        /// <param name="commandKey">The command key</param>
        /// <param name="parameters">The parameters</param>
        /// <returns>Boolean indicating status of the execution</returns>
        private static async Task <bool> Execute(string commandKey, string[] parameters)
        {
            IShellCommand command = await Init.GetCommandWithKeyAsync <IShellCommand>(commandKey).ConfigureAwait(false);

            if (command == null)
            {
                ShellIO.Error("Command doesn't exist. use 'help' to check all available commands!");
                return(false);
            }

            try {
                if (!command.IsInitSuccess)
                {
                    await command.InitAsync().ConfigureAwait(false);
                }

                if (!command.IsCurrentCommandContext(command.CommandKey, parameters.Length))
                {
                    ShellIO.Error("Command doesn't match the syntax. Please retype.");
                    return(false);
                }

                if (!command.HasParameters && parameters.Length > 0)
                {
                    ShellIO.Info($"'{command.CommandName}' doesn't require any arguments.");

                    string args = string.Empty;
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(parameters[i]))
                        {
                            args += parameters[i] + ",";
                        }
                    }

                    ShellIO.Info($"Entered arguments '{args}' will be trimmed out.");
                    parameters = new string[0];
                }

                if (parameters.Length > command.MaxParameterCount)
                {
                    ShellIO.Info($"'{command.CommandName}' only supports a maximum of '{command.MaxParameterCount}' arguments. You have entered '{parameters.Length}'");

                    string args = string.Empty;
                    for (int i = (parameters.Length - command.MaxParameterCount) - 1; i > parameters.Length - command.MaxParameterCount; i--)
                    {
                        parameters[i] = null;
                    }

                    ShellIO.Info($"'{parameters.Length - command.MaxParameterCount}' arguments will be trimmed out.");
                    return(false);
                }

                await Notifications.Notify(Notifications.NotificationType.NotifyShort).ConfigureAwait(false);

                await command.ExecuteAsync(new Parameter(commandKey, parameters)).ConfigureAwait(false);

                return(true);
            }
            finally {
                command.Dispose();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Parses the raw command string value. <br>Then executes it by calling the Execute() method with the parsed values.</br>
        /// </summary>
        /// <param name="cmd">The command <see cref="string"/></param>
        /// <returns>The <see cref="bool"/></returns>
        private static async Task <bool> ParseCommandAsync(string cmd)
        {
            if (Commands.Count <= 0)
            {
                ShellIO.Info("No commands have been loaded into the shell.");
                return(false);
            }

            if (string.IsNullOrEmpty(cmd))
            {
                ShellIO.Error("Invalid command.");
                return(false);
            }

            await Sync.WaitAsync().ConfigureAwait(false);

            bool anyExec = false;

            try {
                // If there is multiple commands separated by the Multi command delimiter
                if (cmd.Contains(ShellConstants.MULTI_COMMAND))
                {
                    //commands - returns {help -argument}
                    string[] cmdSplit = cmd.Split(ShellConstants.MULTI_COMMAND, StringSplitOptions.RemoveEmptyEntries);

                    if (cmdSplit == null || cmdSplit.Length <= 0)
                    {
                        ShellIO.Error("Failed to parse the command. Please retype in correct syntax!");
                        return(false);
                    }

                    // for each -> {help -arg1 -arg2}
                    for (int i = 0; i < cmdSplit.Length; i++)
                    {
                        if (string.IsNullOrEmpty(cmdSplit[i]))
                        {
                            continue;
                        }

                        bool     doesContainArgs = cmdSplit[i].Contains(ShellConstants.ARGUMENT_SPLITTER);
                        string[] parameters      = new string[0];
                        string?  commandKey      = null;

                        // If contains arguments
                        if (doesContainArgs)
                        {
                            string[] cmdArgumentSplit = cmdSplit[i].Split(ShellConstants.ARGUMENT_SPLITTER, StringSplitOptions.RemoveEmptyEntries);
                            if (cmdArgumentSplit == null || cmdArgumentSplit.Length <= 0)
                            {
                                continue;
                            }

                            parameters = new string[cmdArgumentSplit.Length - 1];

                            for (int k = 0; k < cmdArgumentSplit.Length; k++)
                            {
                                if (string.IsNullOrEmpty(cmdArgumentSplit[k]))
                                {
                                    continue;
                                }

                                cmdArgumentSplit[k] = Replace(cmdArgumentSplit[k].Trim());

                                if (string.IsNullOrEmpty(commandKey))
                                {
                                    commandKey = cmdArgumentSplit[k];
                                }

                                if (cmdArgumentSplit[k].Equals(commandKey, StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }

                                parameters[k - 1] = cmdArgumentSplit[k];
                            }
                        }
                        else
                        {
                            // If no arguments
                            commandKey = Replace(cmdSplit[i].Trim());
                        }

                        if (string.IsNullOrEmpty(commandKey))
                        {
                            continue;
                        }

                        if (await Execute(commandKey, parameters).ConfigureAwait(false))
                        {
                            anyExec = true;
                        }
                        continue;
                    }
                }
                else
                {
                    //If there is only single command
                    bool     doesContainArgs = cmd.Contains(ShellConstants.ARGUMENT_SPLITTER);
                    string[] parameters      = new string[0];
                    string?  commandKey      = null;

                    if (doesContainArgs)
                    {
                        string[] cmdArgumentSplit = cmd.Split(ShellConstants.ARGUMENT_SPLITTER, StringSplitOptions.RemoveEmptyEntries);

                        if (cmdArgumentSplit == null || cmdArgumentSplit.Length <= 0)
                        {
                            return(false);
                        }

                        parameters = new string[cmdArgumentSplit.Length - 1];

                        for (int k = 0; k < cmdArgumentSplit.Length; k++)
                        {
                            if (string.IsNullOrEmpty(cmdArgumentSplit[k]))
                            {
                                continue;
                            }

                            cmdArgumentSplit[k] = Replace(cmdArgumentSplit[k].Trim());

                            if (string.IsNullOrEmpty(commandKey))
                            {
                                commandKey = cmdArgumentSplit[k];
                            }

                            if (cmdArgumentSplit[k].Equals(commandKey, StringComparison.OrdinalIgnoreCase))
                            {
                                continue;
                            }

                            parameters[k - 1] = cmdArgumentSplit[k];
                        }
                    }
                    else
                    {
                        commandKey = Replace(cmd.Trim());
                    }

                    if (string.IsNullOrEmpty(commandKey))
                    {
                        return(false);
                    }

                    if (await Execute(commandKey, parameters).ConfigureAwait(false))
                    {
                        anyExec = true;
                    }
                }

                if (!anyExec)
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception e) {
                Logger.Exception(e);
                ShellIO.Error("Internal exception occurred. Execution failed unexpectedly.");
                ShellIO.Exception(e);
                return(false);
            }
            finally {
                Sync.Release();
            }
        }