public async Task <IMessage> PipeCommand(IInvocationContext context, IMessage message) { List <string> cmds = string.Join(" ", message.Text.GetCommandArguments()).Split('|').ToList(); Message basicMessage = Message.Create(message.Text, message.Attachments?.ToArray()); basicMessage.Text = string.Join(" ", cmds.First().Split(' ').Skip(1).ToList()).Trim(); foreach (var cmd in cmds) { List <string> call = cmd.Trim().Split(' ').ToList(); if (!_commandRegistry.Exists(call.First())) { continue; } IMessage result = await _commandRegistry.ExecuteCommandAsync(call.First(), context, call.Count == 1?basicMessage : Message.Create(string.Join(" ", call.Skip(1)))); if (!string.IsNullOrEmpty(result.Text)) { basicMessage.Text = result.Text; } if (result.Attachments != null) { if (basicMessage.Attachments?.Count > 0) { // Prevent leak since we're going out of scope basicMessage.Attachments.ForEach(x => x.Contents?.Dispose()); } basicMessage.Attachments = result.Attachments; } } return(basicMessage); }
private void MessageBusOnReceived(object sender, MessageReceivedEventArgs eventArgs) { // Unpack locally. IInvocationContext context = eventArgs.Context; IMessage message = eventArgs.Message; // Is it a command? if (message.Text?.StartsWith(".") != true) { return; } // Check if command exists. string command = message.Text.Split(' ').First().TrimStart('.'); if (!_commandRegistry.Exists(command)) { Debug.WriteLine($"Invalid command called: {command}"); return; } // Ensure we do not back up the rest of the command invocation queue. // TODO: Per-server task pools. Task.Run(async() => { try { IMessage result = await _commandRegistry.ExecuteCommandAsync(command, context, message); if (result != null) { _messageBus.RaiseOutgoing(context.Raiser, result); } } catch (Exception e) { // Check if there is a help function. var help = _commandRegistry.GetHelp(command); if (!String.IsNullOrEmpty(help)) { _messageBus.RaiseOutgoing(context.Raiser, Message.Create(help)); } else { _messageBus.RaiseOutgoing(context.Raiser, Message.Create("```\n" + e.StackTrace + "\n```", new FileAttachment(Path.Combine(PathExtensions.AppDir, "error.jpg")))); } } }); }
public async Task <IMessage> PipeCommand(IInvocationContext context, IMessage message) { List <string> cmds = string.Join(" ", message.Text.GetCommandArguments()).Split('|').ToList(); Message basicMessage = Message.Create(message.Text, message.Attachments?.ToArray()); basicMessage.Text = string.Join(" ", cmds.First().Split(' ').Skip(1).ToList()).Trim(); bool appendNext = false; foreach (var cmd in cmds) { List <string> call = cmd.Trim().Split(' ').ToList(); if (!_commandRegistry.Exists(call.First())) { // Special commands. if (call[0] == "cleartext") { basicMessage.Text = string.Empty; } else if (call[0] == "clearattachment") { basicMessage.Attachments?.ForEach(x => x.Contents?.Dispose()); basicMessage.Attachments = null; } else if (call[0] == "append") { appendNext = true; } continue; } if (_commandRegistry.IsCommandComplexOrNull(call.First())) { continue; } IMessage result; try { result = await _commandRegistry.ExecuteCommandAsync(call.First(), context, call.Count == 1 ?basicMessage : Message.Create(string.Join(" ", call.Skip(1)), basicMessage.Attachments?.ToArray())); } catch (Exception e) { // Quickly dispose what we can. basicMessage.Attachments?.ForEach(x => x.Contents?.Dispose()); throw (e); } if (!string.IsNullOrEmpty(result.Text)) { basicMessage.Text = result.Text; } if (result.Attachments != null) { if (appendNext) { basicMessage.Attachments?.AddRange(result.Attachments); appendNext = false; } else { if (basicMessage.Attachments?.Count > 0) { // Prevent leak since we're going out of scope basicMessage.Attachments.ForEach(x => x.Contents?.Dispose()); } basicMessage.Attachments = result.Attachments; } } } return(basicMessage); }
private void MessageBusOnReceived(object sender, MessageReceivedEventArgs eventArgs) { // Unpack locally. IInvocationContext context = eventArgs.Context; IMessage message = eventArgs.Message; // Is it a command? if (message.Text?.IsCommand() != true) { return; } // Check if command exists. string command = message.Text.Split(' ').First().TrimStart('.', '!'); if (!_commandRegistry.Exists(command)) { if (command[0] != '.' || command[0] != '!') { if (message is IReactableMessage reactableMessage) { reactableMessage.React("🚫").Forget(); } } return; } IChannelTypingIndicator typingChannel = context?.Channel as IChannelTypingIndicator; // Ensure we do not back up the rest of the command invocation queue. // TODO: Per-server task pools. Task.Run(async() => { try { typingChannel?.SetTyping(true); IMessage result = await _commandRegistry.ExecuteCommandAsync(command, context, message); if (result != null) { _messageBus.RaiseOutgoing(context?.Raiser, result); } typingChannel?.SetTyping(false); if (message.Text[0] == '!') { if (message is IDeletableMessage deletableMessage) { deletableMessage.DeleteAsync().Forget(); } } } catch (Exception e) { typingChannel?.SetTyping(false); // Quickly dispose any streams in memory. message.Attachments?.ForEach(x => x.Contents?.Dispose()); Log.Error($"{command} FAIL: {e}"); if (message is IReactableMessage erroredReactableMessage) { erroredReactableMessage.React("💔").Forget(); } else { // Check if there is a help function. var help = _commandRegistry.GetHelp(command); if (!string.IsNullOrEmpty(help)) { _messageBus.RaiseOutgoing(context.Raiser, Message.Create(help)); } else { #if DEBUG _messageBus.RaiseOutgoing(context.Raiser, Message.Create("```\n" + e.StackTrace + "\n```", new FileAttachment(Path.Combine(PathExtensions.AppDir, "error.jpg")))); #endif } } } }); }