/// <summary> /// Send the result of <see cref="ScriptSayFunction"/>. /// </summary> private static async ValueTask SendResultAsync(IContext e, ScriptSayFunction say) { DiscordEmbed embed = null; if (say.EmbedBuilder != null) { var embedBuilder = say.EmbedBuilder.InnerEmbedBuilder; embed = embedBuilder.ToEmbed(); // Don't send a empty embed to Discord. if (string.IsNullOrWhiteSpace(embed.Description) && string.IsNullOrWhiteSpace(embed.Title) && string.IsNullOrWhiteSpace(embed.Image?.Url) && (embed.Fields?.All(f => string.IsNullOrWhiteSpace(f.Content)) ?? true)) { embed = null; } } var output = say.Output; if (output.Length == 0 && embed == null) { return; } await e.GetChannel().SendMessageAsync(output.ToString(), false, embed); }
private async ValueTask <bool> ExecuteAsync(IContext e, Block block, ICodeProvider codeProvider) { var isDonator = await userService.UserIsDonatorAsync((long)e.GetGuild().OwnerId); var options = isDonator ? DonatorOptions : DefaultOptions; var storage = await CreateStorageAsync(e, isDonator); var say = new ScriptSayFunction(); var global = await CreateGlobalAsync(e, say); var runner = e.GetService <Runner>(); var context = new Context(block, global, runner, options); global["storage"] = storage; try { await runner.ExecuteAsync(context); await SendResultAsync(e, say); await storage.UpdateAsync(context); return(true); } catch (MiScriptLimitException ex) { var type = ex.Type switch { LimitType.Instructions => "instructions", LimitType.Stack => "function calls", LimitType.ArrayItems => "array items", LimitType.ObjectItems => "object items", LimitType.StringLength => "string size", _ => throw new ArgumentOutOfRangeException() }; await e.ErrorEmbedResource("user_error_miscript_limit", type) .ToEmbed().QueueAsync(e, e.GetChannel()); } catch (UserMiScriptException ex) { await SendErrorAsync(e, "user_error_miscript_execute", ex.Value, codeProvider, ex.Position); } catch (MiScriptException ex) { await SendErrorAsync(e, "error_miscript_execute", ex.Message, codeProvider, ex.Position); } catch (Exception ex) { await SendErrorAsync(e, "error_miscript_execute", "Internal error in MiScript: " + ex.Message, codeProvider); } return(false); }