#nullable disable using System.Globalization; // ReSharper disable InconsistentNaming namespace Ellie.Common; [UsedImplicitly(ImplicitUseTargetFlags.Default | ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.WithMembers)] public abstract class EllieModule : ModuleBase { protected CultureInfo Culture { get; set; } // Injected by Discord.net public IBotStrings Strings { get; set; } public ICommandHandler _cmdHandler { get; set; } public ILocalization _localization { get; set; } public IEmbedBuilderService _eb { get; set; } public IEllieInteractionService _inter { get; set; } protected string prefix => _cmdHandler.GetPrefix(ctx.Guild); protected ICommandContext ctx => Context; protected override void BeforeExecute(CommandInfo command) => Culture = _localization.GetCultureInfo(ctx.Guild?.Id); protected string GetText(in LocStr data) => Strings.GetText(data, Culture); public Task<IUserMessage> SendErrorAsync( string title, string error, string url = null, string footer = null, EllieInteraction inter = null) => ctx.Channel.SendErrorAsync(_eb, title, error, url, footer); public Task<IUserMessage> SendConfirmAsync( string title, string text, string url = null, string footer = null) => ctx.Channel.SendConfirmAsync(_eb, title, text, url, footer); // public Task<IUserMessage> SendErrorAsync(string text, EllieInteraction inter = null) => ctx.Channel.SendAsync(_eb, text, MsgType.Error, inter); public Task<IUserMessage> SendConfirmAsync(string text, EllieInteraction inter = null) => ctx.Channel.SendAsync(_eb, text, MsgType.Ok, inter); public Task<IUserMessage> SendPendingAsync(string text, EllieInteraction inter = null) => ctx.Channel.SendAsync(_eb, text, MsgType.Pending, inter); // localized normal public Task<IUserMessage> ErrorLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendErrorAsync(GetText(str), inter); public Task<IUserMessage> PendingLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendPendingAsync(GetText(str), inter); public Task<IUserMessage> ConfirmLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendConfirmAsync(GetText(str), inter); // localized replies public Task<IUserMessage> ReplyErrorLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); public Task<IUserMessage> ReplyPendingLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); public Task<IUserMessage> ReplyConfirmLocalizedAsync(LocStr str, EllieInteraction inter = null) => SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); public async Task<bool> PromptUserConfirmAsync(IEmbedBuilder embed) { embed.WithPendingColor().WithFooter("yes/no"); var msg = await ctx.Channel.EmbedAsync(embed); try { var input = await GetUserInputAsync(ctx.User.Id, ctx.Channel.Id); input = input?.ToUpperInvariant(); if (input != "YES" && input != "Y") return false; return true; } finally { _ = Task.Run(() => msg.DeleteAsync()); } } // TypeConverter typeConverter = TypeDescriptor.GetConverter(propType); ? public async Task<string> GetUserInputAsync(ulong userId, ulong channelId) { var userInputTask = new TaskCompletionSource<string>(); var dsc = (DiscordSocketClient)ctx.Client; try { dsc.MessageReceived += MessageReceived; if (await Task.WhenAny(userInputTask.Task, Task.Delay(10000)) != userInputTask.Task) return null; return await userInputTask.Task; } finally { dsc.MessageReceived -= MessageReceived; } Task MessageReceived(SocketMessage arg) { _ = Task.Run(() => { if (arg is not SocketUserMessage userMsg || userMsg.Channel is not ITextChannel || userMsg.Author.Id != userId || userMsg.Channel.Id != channelId) return Task.CompletedTask; if (userInputTask.TrySetResult(arg.Content)) userMsg.DeleteAfter(1); return Task.CompletedTask; }); return Task.CompletedTask; } } } public abstract class EllieModule<TService> : EllieModule { public TService _service { get; set; } }