Ejemplo n.º 1
0
        public int?Execute <TProgram>(TextWriter consoleOut) where TProgram : IRuntimeProgram, new()
        {
            Console.SetOut(consoleOut);

            var command = new RuntimeCommand();

            var result = command.Execute <TProgram>();

            return(command.Restarted ? (int?)null : result);
        }
Ejemplo n.º 2
0
        public void RuntimeCommand_Test()
        {
            var runtime = new RuntimeCommand();

            runtime.Execute();
        }
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 /// <param name="template">The template that identifies the command - null if this is an application
 /// configuration.</param>
 internal CommandConfiguration(Template?template)
 {
     RuntimeCommand = new RuntimeCommand <TOptions>(template, () => ParserConfig.ArgumentParsers);
 }
Ejemplo n.º 4
0
        public void RunCommands(Connection.ChatEventArgs e = null)
        {
            foreach (string command in CommandStrings)
            {
                string formatted = command.Trim();
                formatted = ParseResult.ReplaceDynamicReferences(formatted, Connection);
                if (command.Trim().StartsWith("!") || command.Trim().StartsWith("%"))
                {
                    if (command.Trim().StartsWith("!!"))
                    {
                        formatted = formatted.TrimStart("@".ToCharArray()); // I don't remember why this is necessary
                    }
                    else
                    {
                        // Remove the command-enclosing '%' characters
                        formatted = command.RemoveFirst('%', 2);
                    }
                    while (formatted.StartsWith("!"))
                    {
                        // Remove '!' characters
                        formatted = formatted.Remove(0, 1);
                    }

                    if (RuntimeCommand.StringStartsWithCommandName(formatted))
                    {
                        RuntimeCommand.TryRunCommand($"!{formatted}", null, Connection);
                    }
                    else
                    {
                        Connection.RconCommandQueue.Enqueue(
                            RconCommand.ConsoleLogCommand(
                                formatted, formatted,
                                e?.SendingPlayer?.Name ?? "SERVER"
                                )
                            );
                    }
                }
                else
                {
                    if (formatted.StartsWith("!"))
                    {
                        if (RuntimeCommand.StringStartsWithCommandName(formatted.TrimStart(1)))
                        {
                            RuntimeCommand.TryRunCommand(formatted, null, Connection);
                        }
                        else
                        {
                            Connection.RconCommandQueue.Enqueue(
                                RconCommand.ConsoleLogCommand(
                                    formatted, formatted,
                                    e?.SendingPlayer?.Name ?? "SERVER"
                                    )
                                );
                        }
                    }
                    else
                    {
                        if (RuntimeCommand.StringStartsWithCommandName(formatted))
                        {
                            RuntimeCommand.TryRunCommand($"!{formatted}", null, Connection);
                        }
                        else
                        {
                            Connection.RconCommandQueue.Enqueue(
                                RconCommand.ConsoleLogCommand(
                                    formatted, formatted,
                                    e?.SendingPlayer?.Name ?? "SERVER"
                                    )
                                );
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generate a <see cref="ParseResult"/> for the specified <see cref="RuntimeCommand"/> (<paramref name="command"/>) by parsing the command string (<paramref name="message"/>) sent by <see cref="PlayerInfo"/> (<paramref name="player"/>) (or RCON connected admin client) for the specified <see cref="Connection"/> (<paramref name="connection"/>), and store the related <see cref="Message"/> (<paramref name="chatMessage"/>) if applicable.
        /// </summary>
        /// <param name="connection">The relevant connection used to Parse the <paramref name="command"/>, respond to the <paramref name="player"/> if applicable, and store the <paramref name="chatMessage"/> if applicable.</param>
        /// <param name="message">The string that will be parsed for args and DynamicReferences for the <see cref="RuntimeCommand"/> being evaluated</param>
        /// <param name="player">The player whose message is being parsed.</param>
        /// <param name="command">The RuntimeCommand being parsed.</param>
        /// <param name="chatMessage">The ChatMessage containing the RuntimeCommand being parsed.</param>
        public ParseResult(Connection connection, string message, PlayerInfo player, RuntimeCommand command, Message chatMessage)
        {
            if (connection == null)
            {
                IsValid = false;
            }

            ChatMessage = chatMessage;

            ReplaceDynamicReferences(message, connection);

            // Add a copy of the command submitted by the player or server to the list of responses

            // To player
            if (player != null)
            {
                if (message.Length + player.Name.Length + 3 > 128)
                {
                    Response.Add("@" + player.Name + ":");
                    // Response.Add(" " + message); <- Previously there was a space here, but I think that would mess up, becuase it would be ' !whatever...', which would be flagged as a command I'm pretty sure
                    Response.Add("@" + message);
                }
                else
                {
                    Response.Add("@" + player.Name + ": " + message);
                }
            }
            // To server
            else
            {
                if (message.Length + 9 > 128)
                {
                    Response.Add("@SERVER:");
                    // Response.Add(" " + message); <- Previously there was a space here, but I think that would mess up, becuase it would be ' !whatever...', which would be flagged as a command I'm pretty sure
                    Response.Add("@" + message);
                }
                else
                {
                    Response.Add($"@SERVER: {message}");
                }
            }

            // Confirm authorization
            if (command.AdminCommand && player != null)
            {
                if (!connection.Settings.AuthorizedUIDs.Contains(player.Uid ?? ""))
                {
                    IsValid = false;
                    Add("You are not authorized to use this command.");
                    return;
                }
            }

            // Process Args
            if (command.Args.Count > 0)
            {
                //TODO '!pm Player "message in quotes"' only sends 'message' - i.e. only the first word of the quoted message
                //TODO '!pm Player message with "quoted content" inside' only sends 'message with quoted' - so it cuts off everything after the first word after quotation mark

                // message with command trigger trimmed
                string content = message.TrimStart(command.Trigger.Length).Trim();

                foreach (Arg arg in command.Args)
                {
                    switch (arg.ArgType)
                    {
                    case Arg.Type.PlayerName:
                        List <string> players = null;
                        lock (connection.State.ServerStateLock)
                        {
                            players = connection.State.Players.Select(x => x.Name).ToList();
                        }
                        Parameters.Add(BestMatch(players, content, arg, false));
                        break;

                    case Arg.Type.BaseMap:
                        Parameters.Add(BestMatch(MapVariant.BaseMapIDsByNameLower.Keys.ToList(), content, arg));
                        break;

                    case Arg.Type.MapName:
                        Parameters.Add(BestMatch(connection.MapVariantNames, content, arg, false));
                        break;

                    case Arg.Type.BaseVariant:
                        Parameters.Add(BestMatch(GameVariant.BaseGamesByNameLower.Keys.ToList(), content, arg));
                        break;

                    case Arg.Type.VariantName:
                        Parameters.Add(BestMatch(connection.GameVariantNames, content, arg, false));
                        break;

                    case Arg.Type.String:
                        Parameters.Add(string.IsNullOrWhiteSpace(content) ? null : content);
                        break;

                    case Arg.Type.FileNameJSON:
                        if (!string.IsNullOrWhiteSpace(content) && content.Contains(".json"))
                        {
                            Parameters.Add(content.Substring(0, content.IndexOf(".json") + 5));
                        }
                        else
                        {
                            Parameters.Add(null);
                        }
                        break;

                    case Arg.Type.LanguageCode:
                        if (!string.IsNullOrWhiteSpace(content) && content.Length >= 4 && content.StartsWith("-") && content.Contains(' '))
                        {
                            // format is "-ab *whatever*" | ab = any language code
                            content = content.TrimStart(1);
                            Parameters.Add(content.Substring(0, content.IndexOf(' ')));
                        }
                        else
                        {
                            Parameters.Add(null);
                        }
                        break;

                    case Arg.Type.CommandName:
                        if (!string.IsNullOrWhiteSpace(content))
                        {
                            ToolCommand toolCommand = connection.Settings.Commands.First(x => x.Name.StartsWith(content));
                            if (toolCommand != null)
                            {
                                Parameters.Add(content);
                            }
                            else
                            {
                                Parameters.Add(null);
                            }
                        }
                        else
                        {
                            Parameters.Add(null);
                        }
                        break;

                    default: break;
                    }

                    if (Parameters[Parameters.Count - 1] != null)
                    {
                        // update content string
                        content = content.Substring(Parameters[Parameters.Count - 1].Length, (content.Length - Parameters[Parameters.Count - 1].Length)).Trim();
                    }
                    else if (arg.IsRequired)
                    {
                        IsValid = false; Response.Add("Command Failed: Unable to parse " + arg.Name + " parameter.");
                    }

                    // Add response and return if invalid
                    if (!IsValid)
                    {
                        switch (arg.ArgType)
                        {
                        case Arg.Type.PlayerName:       Response.Add("Player names must be unquoted and correctly capitalized."); return;

                        case Arg.Type.BaseMap:          Response.Add("Base map names must be unquoted, with any spaces removed."); return;

                        case Arg.Type.MapName:          Response.Add("Map names must be unquoted and correctly capitalized."); return;

                        case Arg.Type.BaseVariant:      Response.Add("Base gametype names must be unquoted, with any spaces removed."); return;

                        case Arg.Type.VariantName:      Response.Add("Game variant names must be unquoted and correctly capitalized."); return;

                        case Arg.Type.FileNameJSON: Response.Add("JSON file names must end in '.json'."); return;

                        case Arg.Type.LanguageCode: Response.Add("Language code format is either '-aa' or '-aa-bb'."); return;

                        case Arg.Type.CommandName:  Response.Add("Command names must be unquoted and correctly capitalized."); return;

                        default: return;
                        }
                    }
                }
            }
        }