public string[] GetSuggestions(string text, int index)
        {
            var args         = text.Substring(0, index).Split(' ').ToArray();
            var commandStart = index >= text.Length ? string.Empty : text.Substring(index, text.Length - index);

            var commands = AsyncHelper.RunSync(() => m_CommandStore.GetCommandsAsync());
            var context  = m_CommandContextBuilder.CreateContext(m_ConsoleActorAccessor.Actor, args, string.Empty, commands);

            IEnumerable <ICommandRegistration> matchingCommands;

            if (context.CommandRegistration == null)
            {
                matchingCommands = commands.Where(d =>
                                                  d.ParentId == null &&
                                                  d.Name.StartsWith(commandStart, StringComparison.OrdinalIgnoreCase));
            }
            else
            {
                matchingCommands = commands.Where(d =>
                                                  !string.IsNullOrEmpty(d.ParentId) &&
                                                  d.ParentId.Equals(context.CommandRegistration.Id, StringComparison.OrdinalIgnoreCase) &&
                                                  d.Name.StartsWith(commandStart, StringComparison.OrdinalIgnoreCase));
            }

            AsyncHelper.RunSync(async() => await context.DisposeAsync());
            return(matchingCommands.Select(d => d.Name).ToArray());
        }
Example #2
0
        protected override async Task OnExecuteAsync()
        {
            var commands = await m_CommandStore.GetCommandsAsync();

            var totalCount = commands.Count;

            const int itemsPerPage = 10;

            int currentPage = 1;

            if (Context.Parameters.Length == 0 || Context.Parameters.TryGet(0, out currentPage))
            {
                if (currentPage < 1)
                {
                    throw new CommandWrongUsageException(Context);
                }

                var pageCommands = commands
                                   .Where(d => d.ParentId == null)
                                   .Skip(itemsPerPage * (currentPage - 1))
                                   .Take(itemsPerPage)
                                   .ToList();

                await PrintPageAsync(currentPage, (int)Math.Ceiling((double)totalCount / itemsPerPage), pageCommands);
            }
            else if (Context.Parameters.Length > 0)
            {
                var context    = m_CommandContextBuilder.CreateContext(Context.Actor, Context.Parameters.ToArray(), Context.CommandPrefix, commands);
                var permission = GetPermission(context.CommandRegistration, commands);

                if (context.CommandRegistration == null)
                {
                    await Context.Actor.PrintMessageAsync(m_StringLocalizer["commands:errors:not_found", new { CommandName = context.GetCommandLine(false) }], Color.Red);

                    return;
                }

                if (!string.IsNullOrEmpty(permission) && await m_PermissionChecker.CheckPermissionAsync(Context.Actor, permission) != PermissionGrantResult.Grant)
                {
                    throw new NotEnoughPermissionException(m_StringLocalizer, permission);
                }

                await PrintCommandHelpAsync(context, permission, commands);

                await context.DisposeAsync();
            }
        }
Example #3
0
        public async Task WriteHelpFileAsync()
        {
            StringBuilder markdownBuilder = new StringBuilder();

            markdownBuilder.Append("# ").AppendLine(m_Plugin.DisplayName);
            markdownBuilder.Append("Id: ").AppendLine(m_Plugin.OpenModComponentId);
            markdownBuilder.Append("Version: ").AppendLine(m_Plugin.Version.ToString());
            if (!string.IsNullOrEmpty(m_Plugin.Author))
            {
                markdownBuilder.Append("Author: ").AppendLine(m_Plugin.Author);
            }
            if (!string.IsNullOrEmpty(m_Plugin.Website))
            {
                markdownBuilder.Append("Website: ").AppendLine(m_Plugin.Website);
            }

            var commands = (await m_CommandStore.GetCommandsAsync())
                           .Where(d => d.Component == m_Plugin)
                           .ToList();

            var rootCommands = commands
                               .Where(d => string.IsNullOrEmpty(d.ParentId));

            if (rootCommands.Any())
            {
                markdownBuilder.AppendLine();
                markdownBuilder.AppendLine("## Commands");
                foreach (var currentCommand in rootCommands)
                {
                    var ctx = m_CommandContextBuilder.CreateContext(null, new string[] { currentCommand.Name }, string.Empty, commands);
                    AppendCommand(markdownBuilder, currentCommand, commands, ctx);
                }
            }

            var permissions = m_PermissionRegistry.GetPermissions(m_Plugin)
                              .Where(d => !m_PrintedCommandPermissions.Any(e =>
                                                                           e.Permission.Equals(d.Permission, StringComparison.OrdinalIgnoreCase)));

            if (permissions.Any())
            {
                markdownBuilder.AppendLine();
                markdownBuilder.AppendLine("## Permissions");
                foreach (var permission in permissions)
                {
                    markdownBuilder.Append("- ").Append(permission.Owner.OpenModComponentId).Append(':').Append(permission.Permission);
                    if (!string.IsNullOrEmpty(permission.Description))
                    {
                        markdownBuilder.Append(": ").Append(permission.Description);
                    }

                    markdownBuilder.AppendLine();
                }
            }

            var directory = m_Plugin.WorkingDirectory;

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            var filePath = Path.Combine(directory, "help.md");

            File.WriteAllText(filePath, markdownBuilder.ToString());
        }
Example #4
0
        public async Task <ICommandContext> ExecuteAsync(ICommandActor actor, string[] args, string prefix)
        {
            if (args == null || args.Length == 0)
            {
                throw new Exception("Cannot execute command with null or empty args.");
            }

            m_Logger.LogInformation("Actor {ActorType}/{ActorName} has executed command \"{Command}\"",
                                    actor.Type, actor.FullActorName, string.Join(" ", args));

            var currentCommandAccessor = m_LifetimeScope.Resolve <ICurrentCommandContextAccessor>();
            var commandContextBuilder  = m_LifetimeScope.Resolve <ICommandContextBuilder>();
            var stringLocalizer        = m_LifetimeScope.Resolve <IOpenModStringLocalizer>();

            var commandsRegistrations = await m_CommandStore.GetCommandsAsync();

            var commandContext        = commandContextBuilder.CreateContext(actor, args, prefix, commandsRegistrations);
            var commandExecutingEvent = new CommandExecutingEvent(actor, commandContext);
            await m_EventBus.EmitAsync(m_Runtime, this, commandExecutingEvent);

            if (commandExecutingEvent.IsCancelled)
            {
                return(commandExecutingEvent.CommandContext);
            }

            try
            {
                if (commandContext.Exception != null)
                {
                    throw commandContext.Exception;
                }

                currentCommandAccessor.Context = commandContext;

                var permission        = m_CommandPermissionBuilder.GetPermission(commandContext.CommandRegistration !);
                var permissionChecker = m_Runtime.LifetimeScope.Resolve <IPermissionChecker>();

                if (!string.IsNullOrWhiteSpace(permission) && await permissionChecker.CheckPermissionAsync(actor, permission) != PermissionGrantResult.Grant)
                {
                    throw new NotEnoughPermissionException(stringLocalizer, permission);
                }

                var sw = new Stopwatch();
                sw.Start();
                var command = commandContext.CommandRegistration !.Instantiate(commandContext.ServiceProvider);
                await command.ExecuteAsync();

                m_Logger.LogDebug("Command \"{Command}\" executed in {Ms}ms",
                                  string.Join(" ", args), sw.ElapsedMilliseconds);

                currentCommandAccessor.Context = null;
            }
            catch (UserFriendlyException ex)
            {
                commandContext.Exception = ex;
            }
            catch (Exception ex)
            {
                commandContext.Exception = ex;
            }
            finally
            {
                var commandExecutedEvent = new CommandExecutedEvent(actor, commandContext);
                await m_EventBus.EmitAsync(m_Runtime, this, commandExecutedEvent);

                if (commandContext.Exception != null && !commandExecutedEvent.ExceptionHandled)
                {
                    if (commandContext.Exception is UserFriendlyException)
                    {
                        await actor.PrintMessageAsync(commandContext.Exception.Message, Color.DarkRed);
                    }
                    else
                    {
                        await actor.PrintMessageAsync("An internal error occured during the command execution.", Color.DarkRed);

                        m_Logger.LogError(commandContext.Exception,
                                          "Exception occured on command \"{Command}\" by actor {ActorType}/{ActorName} ({ActorId})",
                                          string.Join(" ", args), actor.Type, actor.DisplayName, actor.Id);
                    }
                }

                await commandContext.DisposeAsync();
            }

            return(commandContext);
        }
Example #5
0
        public async Task <ICommandContext> ExecuteAsync(ICommandActor actor, string[] args, string prefix)
        {
            if (args == null || args.Length == 0)
            {
                throw new Exception("Can not execute command with null or empty args");
            }

            var logger = m_LifetimeScope.Resolve <ILogger <CommandExecutor> >();

            logger.LogInformation($"Actor {actor.Type}/{actor.DisplayName} ({actor.Id}) has executed command \"{string.Join(" ", args)}\".");

            var currentCommandAccessor = m_LifetimeScope.Resolve <ICurrentCommandContextAccessor>();
            var commandsRegistrations  = await m_CommandStore.GetCommandsAsync();

            var commandContextBuilder = m_LifetimeScope.Resolve <ICommandContextBuilder>();
            var stringLocalizer       = m_LifetimeScope.Resolve <IOpenModStringLocalizer>();
            var commandContext        = commandContextBuilder.CreateContext(actor, args, prefix, commandsRegistrations);

            var commandExecutingEvent = new CommandExecutingEvent(actor, commandContext);
            await m_EventBus.EmitAsync(m_Runtime, this, commandExecutingEvent);

            if (commandExecutingEvent.IsCancelled)
            {
                return(commandExecutingEvent.CommandContext);
            }

            try
            {
                if (commandContext.Exception != null)
                {
                    throw commandContext.Exception;
                }

                currentCommandAccessor.Context = commandContext;

                var permission        = m_CommandPermissionBuilder.GetPermission(commandContext.CommandRegistration);
                var permissionChecker = commandContext.ServiceProvider.GetRequiredService <IPermissionChecker>();

                if (!string.IsNullOrWhiteSpace(permission) && await permissionChecker.CheckPermissionAsync(actor, permission) != PermissionGrantResult.Grant)
                {
                    throw new NotEnoughPermissionException(stringLocalizer, permission);
                }

                var command = commandContext.CommandRegistration.Instantiate(commandContext.ServiceProvider);
                await command.ExecuteAsync();

                currentCommandAccessor.Context = null;
            }
            catch (UserFriendlyException ex)
            {
                commandContext.Exception = ex;
            }
            catch (Exception ex)
            {
                commandContext.Exception = ex;
#if DEBUG
                throw; // in debug mode we want to debug such exceptions instead of catching them
#endif
            }
            finally
            {
                var commandExecutedEvent = new CommandExecutedEvent(actor, commandContext);
                await m_EventBus.EmitAsync(m_Runtime, this, commandExecutedEvent);

                if (commandContext.Exception != null && !commandExecutedEvent.ExceptionHandled)
                {
                    if (commandContext.Exception is UserFriendlyException)
                    {
                        await actor.PrintMessageAsync(commandContext.Exception.Message, Color.DarkRed);
                    }
                    else
                    {
                        await actor.PrintMessageAsync("An internal error occured during the command execution.", Color.DarkRed);

                        logger.LogError(commandContext.Exception, $"Exception occured on command \"{string.Join(" ", args)}\" by actor {actor.Type}/{actor.DisplayName} ({actor.Id})");
                    }
                }

                await commandContext.DisposeAsync();
            }

            return(commandContext);
        }
Example #6
0
        public async Task WriteHelpFileAsync()
        {
            var directory = m_Plugin.WorkingDirectory;

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            StringBuilder markdownBuilder = new StringBuilder();

            markdownBuilder.AppendLine($"# {m_Plugin.DisplayName}");
            markdownBuilder.AppendLine($"Id:  {m_Plugin.OpenModComponentId}  ");
            markdownBuilder.AppendLine($"Version:  {m_Plugin.Version}  ");
            if (!string.IsNullOrEmpty(m_Plugin.Author))
            {
                markdownBuilder.AppendLine($"Author: {m_Plugin.Author}  ");
            }
            if (!string.IsNullOrEmpty(m_Plugin.Website))
            {
                markdownBuilder.AppendLine($"Website: {m_Plugin.Website}  ");
            }

            var commands = (await m_CommandStore.GetCommandsAsync())
                           .Where(d => d.Component == m_Plugin)
                           .ToList();

            var rootCommands = commands
                               .Where(d => string.IsNullOrEmpty(d.ParentId))
                               .ToList();

            if (rootCommands.Count > 0)
            {
                markdownBuilder.AppendLine();
                markdownBuilder.AppendLine("## Commands");
                foreach (var currentCommand in rootCommands)
                {
                    var args = new List <string> {
                        currentCommand.Name
                    };
                    AppendCommand(markdownBuilder, currentCommand, commands, args);
                }
            }

            var permissions = m_PermissionRegistry.GetPermissions(m_Plugin)
                              .Where(d => !m_PrintedCommandPermissions.Any(e =>
                                                                           e.Permission.Equals(d.Permission, StringComparison.OrdinalIgnoreCase)))
                              .ToList();

            if (permissions.Count > 0)
            {
                markdownBuilder.AppendLine();
                markdownBuilder.AppendLine("## Permissions");
                foreach (var permission in permissions)
                {
                    markdownBuilder.Append($"  - {permission.Owner.OpenModComponentId}:{permission.Permission}");
                    if (!string.IsNullOrEmpty(permission.Description))
                    {
                        markdownBuilder.Append($": {permission.Description}");
                    }

                    markdownBuilder.AppendLine("  ");
                }
            }

            var filePath = Path.Combine(directory, "help.md");

            File.WriteAllText(filePath, markdownBuilder.ToString());
        }