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()); }
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(); } }
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()); }
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); }
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); }
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()); }