mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2024-10-02 20:13:13 +00:00
part 3 of the response rework
This commit is contained in:
parent
d28c7b500d
commit
daa2177559
65 changed files with 508 additions and 625 deletions
|
@ -52,6 +52,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
|||
- `.poll` commands removed, discord added polls.
|
||||
- `.scpl` and other music soundcloud commands have been removed as soundcloud isn't issuing new api tokens for years now
|
||||
- Removed a lot of useless and nsfw commands
|
||||
- Removed log voice presence TTS
|
||||
|
||||
## [4.3.22] - 23.04.2023
|
||||
|
||||
|
|
|
@ -40,13 +40,4 @@ public abstract class AnyContext
|
|||
/// <param name="args">Arguments (if any) to format in</param>
|
||||
/// <returns>A formatted localized string</returns>
|
||||
public abstract string GetText(string key, object[]? args = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a context-aware <see cref="IEmbedBuilder"/> instance
|
||||
/// (future feature for guild-based embed colors)
|
||||
/// Any code dealing with embeds should use it for future-proofness
|
||||
/// instead of manually creating embedbuilder instances
|
||||
/// </summary>
|
||||
/// <returns>A context-aware <see cref="IEmbedBuilder"/> instance </returns>
|
||||
public abstract EmbedBuilder Embed();
|
||||
}
|
|
@ -14,13 +14,13 @@
|
|||
//
|
||||
// // unlocalized
|
||||
// public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
// => ch.EmbedAsync(ctx.Embed().WithOkColor().WithDescription(msg));
|
||||
// => _sender.Response(ch).Embed(ctx.Embed().WithOkColor().WithDescription(msg)).SendAsync();
|
||||
//
|
||||
// public static Task<IUserMessage> SendPendingAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
// => ch.EmbedAsync(ctx.Embed().WithPendingColor().WithDescription(msg));
|
||||
// => _sender.Response(ch).Embed(ctx.Embed().WithPendingColor().WithDescription(msg)).SendAsync();
|
||||
//
|
||||
// public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
// => ch.EmbedAsync(ctx.Embed().WithErrorColor().WithDescription(msg));
|
||||
// => _sender.Response(ch).Embed(ctx.Embed().WithErrorColor().WithDescription(msg)).SendAsync();
|
||||
//
|
||||
// // unlocalized
|
||||
// public static Task<IUserMessage> SendConfirmAsync(this AnyContext ctx, string msg)
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using Discord;
|
||||
|
||||
namespace NadekoBot;
|
||||
|
||||
public interface IEmbedBuilder
|
||||
{
|
||||
EmbedBuilder WithDescription(string? desc);
|
||||
EmbedBuilder WithTitle(string? title);
|
||||
EmbedBuilder AddField(string title, object value, bool isInline = false);
|
||||
EmbedBuilder WithFooter(string text, string? iconUrl = null);
|
||||
EmbedBuilder WithAuthor(string name, string? iconUrl = null, string? url = null);
|
||||
EmbedBuilder WithColor(EmbedColor color);
|
||||
EmbedBuilder WithDiscordColor(Color color);
|
||||
Embed Build();
|
||||
EmbedBuilder WithUrl(string url);
|
||||
EmbedBuilder WithImageUrl(string url);
|
||||
EmbedBuilder WithThumbnailUrl(string url);
|
||||
}
|
|
@ -32,6 +32,7 @@ public class LogSetting : DbEntity
|
|||
//voicepresence
|
||||
|
||||
public ulong? LogVoicePresenceId { get; set; }
|
||||
|
||||
public ulong? LogVoicePresenceTTSId { get; set; }
|
||||
public ulong? LogWarnsId { get; set; }
|
||||
}
|
|
@ -19,18 +19,21 @@ public class GreetService : INService, IReadyExecutor
|
|||
private readonly GreetGrouper<IUser> _byes = new();
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public GreetService(
|
||||
DiscordSocketClient client,
|
||||
IBot bot,
|
||||
DbService db,
|
||||
BotConfigService bss,
|
||||
IMessageSenderService sender,
|
||||
IReplacementService repSvc)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
_bss = bss;
|
||||
_repSvc = repSvc;
|
||||
_sender = sender;
|
||||
|
||||
_guildConfigsCache = new(bot.AllGuildConfigs.ToDictionary(g => g.GuildId, GreetSettings.Create));
|
||||
|
||||
|
@ -281,6 +284,7 @@ public class GreetService : INService, IReadyExecutor
|
|||
FullMode = BoundedChannelFullMode.DropNewest
|
||||
});
|
||||
|
||||
|
||||
private async Task<bool> GreetDmUser(GreetSettings conf, IGuildUser user)
|
||||
{
|
||||
var completionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
@ -298,32 +302,32 @@ public class GreetService : INService, IReadyExecutor
|
|||
// .Build();
|
||||
|
||||
var repCtx = new ReplacementContext(client: _client, guild: user.Guild, users: user);
|
||||
var text = SmartText.CreateFrom(conf.DmGreetMessageText);
|
||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||
var smartText = SmartText.CreateFrom(conf.DmGreetMessageText);
|
||||
smartText = await _repSvc.ReplaceAsync(smartText, repCtx);
|
||||
|
||||
if (text is SmartPlainText pt)
|
||||
if (smartText is SmartPlainText pt)
|
||||
{
|
||||
text = new SmartEmbedText()
|
||||
smartText = new SmartEmbedText()
|
||||
{
|
||||
Description = pt.Text
|
||||
};
|
||||
}
|
||||
|
||||
if (text is SmartEmbedText set)
|
||||
if (smartText is SmartEmbedText set)
|
||||
{
|
||||
text = set with
|
||||
smartText = set with
|
||||
{
|
||||
Footer = CreateFooterSource(user)
|
||||
};
|
||||
}
|
||||
else if (text is SmartEmbedTextArray seta)
|
||||
else if (smartText is SmartEmbedTextArray seta)
|
||||
{
|
||||
// if the greet dm message is a text array
|
||||
var ebElem = seta.Embeds.LastOrDefault();
|
||||
if (ebElem is null)
|
||||
{
|
||||
// if there are no embeds, add an embed with the footer
|
||||
text = seta with
|
||||
smartText = seta with
|
||||
{
|
||||
Embeds = new[]
|
||||
{
|
||||
|
@ -355,7 +359,7 @@ public class GreetService : INService, IReadyExecutor
|
|||
}
|
||||
}
|
||||
|
||||
await user.SendAsync(text);
|
||||
await _sender.Response(user).Text(smartText).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -31,13 +31,13 @@ public class MuteService : INService
|
|||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly DbService _db;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public MuteService(DiscordSocketClient client, DbService db, IEmbedBuilderService eb)
|
||||
public MuteService(DiscordSocketClient client, DbService db, IMessageSenderService sender)
|
||||
{
|
||||
_client = client;
|
||||
_db = db;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
|
@ -122,13 +122,13 @@ public class MuteService : INService
|
|||
if (string.IsNullOrWhiteSpace(reason))
|
||||
return;
|
||||
|
||||
_ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder()
|
||||
.WithDescription(
|
||||
$"You've been muted in {user.Guild} server")
|
||||
.AddField("Mute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason)
|
||||
.Build()));
|
||||
_ = Task.Run(() => _sender.Response(user)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithDescription($"You've been muted in {user.Guild} server")
|
||||
.AddField("Mute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.SendAsync());
|
||||
}
|
||||
|
||||
private void OnUserUnmuted(
|
||||
|
@ -140,13 +140,13 @@ public class MuteService : INService
|
|||
if (string.IsNullOrWhiteSpace(reason))
|
||||
return;
|
||||
|
||||
_ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder()
|
||||
.WithDescription(
|
||||
$"You've been unmuted in {user.Guild} server")
|
||||
.AddField("Unmute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason)
|
||||
.Build()));
|
||||
_ = Task.Run(() => _sender.Response(user)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithDescription($"You've been unmuted in {user.Guild} server")
|
||||
.AddField("Unmute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.SendAsync());
|
||||
}
|
||||
|
||||
private Task Client_UserJoined(IGuildUser usr)
|
||||
|
|
|
@ -10,16 +10,16 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
|
|||
private readonly IBotCredsProvider _bcp;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IEmbedBuilderService _ebs;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public CheckForUpdatesService(BotConfigService bcs, IBotCredsProvider bcp, IHttpClientFactory httpFactory,
|
||||
DiscordSocketClient client, IEmbedBuilderService ebs)
|
||||
DiscordSocketClient client, IMessageSenderService sender)
|
||||
{
|
||||
_bcs = bcs;
|
||||
_bcp = bcp;
|
||||
_httpFactory = httpFactory;
|
||||
_client = client;
|
||||
_ebs = ebs;
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
|
@ -86,7 +86,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
|
|||
.WithDescription(thisVersionChangelog.TrimTo(4096))
|
||||
.WithFooter("You may disable these messages by typing '.conf bot checkforupdates false'");
|
||||
|
||||
await user.EmbedAsync(eb);
|
||||
await _sender.Response(user).Embed(eb).SendAsync();
|
||||
}).WhenAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
//keys
|
||||
private readonly TypedKey<ActivityPubData> _activitySetKey;
|
||||
|
@ -40,7 +40,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
IHttpClientFactory factory,
|
||||
BotConfigService bss,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb)
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_cmdHandler = cmdHandler;
|
||||
_db = db;
|
||||
|
@ -50,7 +50,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
_httpFactory = factory;
|
||||
_bss = bss;
|
||||
_pubSub = pubSub;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_activitySetKey = new("activity.set");
|
||||
_guildLeaveKey = new("guild.leave");
|
||||
|
||||
|
@ -225,7 +225,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
{
|
||||
try
|
||||
{
|
||||
await ownerCh.Response(_strings, _eb).Confirm(title, toSend).SendAsync();
|
||||
await _sender.Response(ownerCh).Confirm(title, toSend).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -238,7 +238,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
try
|
||||
{
|
||||
if (_client.GetChannel(cid) is ITextChannel ch)
|
||||
await ch.Response(_strings, _eb).Confirm(title, toSend).SendAsync();
|
||||
await _sender.Response(ch).Confirm(title, toSend).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -252,7 +252,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||
{
|
||||
try
|
||||
{
|
||||
await firstOwnerChannel.Response(_strings, _eb).Confirm(title, toSend).SendAsync();
|
||||
await _sender.Response(firstOwnerChannel).Confirm(title, toSend).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -22,7 +22,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
private readonly MuteService _mute;
|
||||
private readonly ProtectionService _prot;
|
||||
private readonly GuildTimezoneService _tz;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
|
||||
private readonly ConcurrentHashSet<ulong> _ignoreMessageIds = new();
|
||||
|
@ -37,20 +36,18 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
ProtectionService prot,
|
||||
GuildTimezoneService tz,
|
||||
IMemoryCache memoryCache,
|
||||
IEmbedBuilderService eb,
|
||||
UserPunishService punishService,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_client = client;
|
||||
_memoryCache = memoryCache;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_strings = strings;
|
||||
_db = db;
|
||||
_mute = mute;
|
||||
_prot = prot;
|
||||
_tz = tz;
|
||||
_punishService = punishService;
|
||||
_sender = sender;
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
|
@ -73,7 +70,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
_client.UserLeft += _client_UserLeft;
|
||||
// _client.PresenceUpdated += _client_UserPresenceUpdated;
|
||||
_client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated;
|
||||
_client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated_TTS;
|
||||
_client.GuildMemberUpdated += _client_GuildUserUpdated;
|
||||
_client.PresenceUpdated += _client_PresenceUpdated;
|
||||
_client.UserUpdated += _client_UserUpdated;
|
||||
|
@ -168,11 +164,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
|
||||
var title = GetText(logChannel.Guild, strs.thread_deleted);
|
||||
|
||||
await logChannel.EmbedAsync(new EmbedBuilder()
|
||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("🗑 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
.WithFooter(CurrentTime(ch.Guild))).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -198,11 +194,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
|
||||
var title = GetText(logChannel.Guild, strs.thread_created);
|
||||
|
||||
await logChannel.EmbedAsync(new EmbedBuilder()
|
||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("🆕 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
.WithFooter(CurrentTime(ch.Guild))).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -313,7 +309,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
logSetting.UserLeftId = logSetting.UserBannedId = logSetting.UserUnbannedId = logSetting.UserUpdatedId =
|
||||
logSetting.ChannelCreatedId = logSetting.ChannelDestroyedId = logSetting.ChannelUpdatedId =
|
||||
logSetting.LogUserPresenceId = logSetting.LogVoicePresenceId = logSetting.UserMutedId =
|
||||
logSetting.LogVoicePresenceTTSId = logSetting.ThreadCreatedId = logSetting.ThreadDeletedId
|
||||
logSetting.ThreadCreatedId = logSetting.ThreadDeletedId
|
||||
= logSetting.LogWarnsId = value ? channelId : null;
|
||||
await uow.SaveChangesAsync();
|
||||
GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting);
|
||||
|
@ -339,7 +335,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
.AddField("Reason", string.IsNullOrWhiteSpace(arg.Reason) ? "-" : arg.Reason, true)
|
||||
.WithFooter(CurrentTime(g));
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
private Task _client_UserUpdated(SocketUser before, SocketUser uAfter)
|
||||
|
@ -389,7 +385,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
else
|
||||
return;
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -451,10 +447,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
case LogType.VoicePresence:
|
||||
channelId = logSetting.LogVoicePresenceId = logSetting.LogVoicePresenceId is null ? cid : default;
|
||||
break;
|
||||
case LogType.VoicePresenceTts:
|
||||
channelId = logSetting.LogVoicePresenceTTSId =
|
||||
logSetting.LogVoicePresenceTTSId is null ? cid : default;
|
||||
break;
|
||||
case LogType.UserWarned:
|
||||
channelId = logSetting.LogWarnsId = logSetting.LogWarnsId is null ? cid : default;
|
||||
break;
|
||||
|
@ -472,48 +464,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
return channelId is not null;
|
||||
}
|
||||
|
||||
private Task _client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, SocketVoiceState after)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iusr is not IGuildUser usr)
|
||||
return;
|
||||
|
||||
var beforeVch = before.VoiceChannel;
|
||||
var afterVch = after.VoiceChannel;
|
||||
|
||||
if (beforeVch == afterVch)
|
||||
return;
|
||||
|
||||
if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting)
|
||||
|| logSetting.LogVoicePresenceTTSId is null)
|
||||
return;
|
||||
|
||||
ITextChannel? logChannel;
|
||||
if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTts)) is null)
|
||||
return;
|
||||
|
||||
var str = string.Empty;
|
||||
if (beforeVch?.Guild == afterVch?.Guild)
|
||||
str = GetText(logChannel.Guild, strs.log_vc_moved(usr.Username, beforeVch?.Name, afterVch?.Name));
|
||||
else if (beforeVch is null)
|
||||
str = GetText(logChannel.Guild, strs.log_vc_joined(usr.Username, afterVch?.Name));
|
||||
else if (afterVch is null)
|
||||
str = GetText(logChannel.Guild, strs.log_vc_left(usr.Username, beforeVch.Name));
|
||||
|
||||
var toDelete = await logChannel.SendMessageAsync(str, true);
|
||||
toDelete.DeleteAfter(5);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void MuteCommands_UserMuted(
|
||||
IGuildUser usr,
|
||||
IUser mod,
|
||||
|
@ -551,7 +501,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
.WithFooter(CurrentTime(usr.Guild))
|
||||
.WithOkColor();
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -601,7 +551,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
if (!string.IsNullOrWhiteSpace(reason))
|
||||
embed.WithDescription(reason);
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -653,7 +603,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
.WithFooter(CurrentTime(logChannel.Guild))
|
||||
.WithOkColor();
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -711,7 +661,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
.AddField(GetText(logChannel.Guild, strs.new_nick),
|
||||
$"{after.Nickname}#{after.Discriminator}");
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
else if (!before.Roles.SequenceEqual(after.Roles))
|
||||
{
|
||||
|
@ -721,7 +671,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
embed.WithAuthor("⚔ " + GetText(logChannel.Guild, strs.user_role_add))
|
||||
.WithDescription(string.Join(", ", diffRoles).SanitizeMentions());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
else if (before.Roles.Count > after.Roles.Count)
|
||||
{
|
||||
|
@ -735,7 +685,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
embed.WithAuthor("⚔ " + GetText(logChannel.Guild, strs.user_role_rem))
|
||||
.WithDescription(string.Join(", ", diffRoles).SanitizeMentions());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -791,7 +741,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
else
|
||||
return;
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -826,11 +776,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
else
|
||||
title = GetText(logChannel.Guild, strs.text_chan_destroyed);
|
||||
|
||||
await logChannel.EmbedAsync(new EmbedBuilder()
|
||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("🆕 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
.WithFooter(CurrentTime(ch.Guild))).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -862,11 +812,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
else
|
||||
title = GetText(logChannel.Guild, strs.text_chan_created);
|
||||
|
||||
await logChannel.EmbedAsync(new EmbedBuilder()
|
||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("🆕 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
.WithFooter(CurrentTime(ch.Guild))).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -975,7 +925,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(usr.GetAvatarUrl());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -1014,7 +964,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(usr.GetAvatarUrl());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -1049,7 +999,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(usr.GetAvatarUrl());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -1099,7 +1049,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
if (Uri.IsWellFormedUriString(avatarUrl, UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(usr.GetAvatarUrl());
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -1152,7 +1102,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
string.Join(", ", msg.Attachments.Select(a => a.Url)));
|
||||
}
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -1212,7 +1162,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
.AddField("Id", after.Id.ToString())
|
||||
.WithFooter(CurrentTime(channel.Guild));
|
||||
|
||||
await logChannel.EmbedAsync(embed);
|
||||
await _sender.Response(logChannel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -1266,9 +1216,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
case LogType.VoicePresence:
|
||||
id = logSetting.LogVoicePresenceId;
|
||||
break;
|
||||
case LogType.VoicePresenceTts:
|
||||
id = logSetting.LogVoicePresenceTTSId;
|
||||
break;
|
||||
case LogType.UserMuted:
|
||||
id = logSetting.UserMutedId;
|
||||
break;
|
||||
|
@ -1348,9 +1295,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||
case LogType.VoicePresence:
|
||||
newLogSetting.LogVoicePresenceId = null;
|
||||
break;
|
||||
case LogType.VoicePresenceTts:
|
||||
newLogSetting.LogVoicePresenceTTSId = null;
|
||||
break;
|
||||
case LogType.UserWarned:
|
||||
newLogSetting.LogWarnsId = null;
|
||||
break;
|
||||
|
|
|
@ -145,8 +145,6 @@ public partial class Administration
|
|||
return l.LogUserPresenceId;
|
||||
case LogType.VoicePresence:
|
||||
return l.LogVoicePresenceId;
|
||||
case LogType.VoicePresenceTts:
|
||||
return l.LogVoicePresenceTTSId;
|
||||
case LogType.UserMuted:
|
||||
return l.UserMutedId;
|
||||
case LogType.UserWarned:
|
||||
|
|
|
@ -65,11 +65,13 @@ public partial class Administration
|
|||
var dmFailed = false;
|
||||
try
|
||||
{
|
||||
await user.EmbedAsync(new EmbedBuilder()
|
||||
.WithErrorColor()
|
||||
.WithDescription(GetText(strs.warned_on(ctx.Guild.ToString())))
|
||||
.AddField(GetText(strs.moderator), ctx.User.ToString())
|
||||
.AddField(GetText(strs.reason), reason ?? "-"));
|
||||
await _sender.Response(user)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithErrorColor()
|
||||
.WithDescription(GetText(strs.warned_on(ctx.Guild.ToString())))
|
||||
.AddField(GetText(strs.moderator), ctx.User.ToString())
|
||||
.AddField(GetText(strs.reason), reason ?? "-"))
|
||||
.SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -84,7 +86,8 @@ public partial class Administration
|
|||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Exception occured while warning a user");
|
||||
var errorEmbed = new EmbedBuilder().WithErrorColor().WithDescription(GetText(strs.cant_apply_punishment));
|
||||
var errorEmbed = new EmbedBuilder().WithErrorColor()
|
||||
.WithDescription(GetText(strs.cant_apply_punishment));
|
||||
|
||||
if (dmFailed)
|
||||
errorEmbed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -261,9 +264,9 @@ public partial class Administration
|
|||
});
|
||||
|
||||
return new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.warnings_list))
|
||||
.WithDescription(string.Join("\n", ws));
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.warnings_list))
|
||||
.WithDescription(string.Join("\n", ws));
|
||||
},
|
||||
warnings.Length,
|
||||
15);
|
||||
|
@ -433,9 +436,10 @@ public partial class Administration
|
|||
try
|
||||
{
|
||||
var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg));
|
||||
var embed = await _service.GetBanUserDmEmbed(Context, guildUser, defaultMessage, msg, time.Time);
|
||||
if (embed is not null)
|
||||
await guildUser.SendAsync(embed);
|
||||
var smartText =
|
||||
await _service.GetBanUserDmEmbed(Context, guildUser, defaultMessage, msg, time.Time);
|
||||
if (smartText is not null)
|
||||
await Response().User(guildUser).Text(smartText).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -447,13 +451,13 @@ public partial class Administration
|
|||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||
await _mute.TimedBan(ctx.Guild, userId, time.Time, (ctx.User + " | " + msg).TrimTo(512), banPrune);
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true)
|
||||
.AddField("ID", userId.ToString(), true)
|
||||
.AddField(GetText(strs.duration),
|
||||
time.Time.Humanize(3, minUnit: TimeUnit.Minute, culture: Culture),
|
||||
true);
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true)
|
||||
.AddField("ID", userId.ToString(), true)
|
||||
.AddField(GetText(strs.duration),
|
||||
time.Time.Humanize(3, minUnit: TimeUnit.Minute, culture: Culture),
|
||||
true);
|
||||
|
||||
if (dmFailed)
|
||||
toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -475,9 +479,9 @@ public partial class Administration
|
|||
await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
||||
|
||||
await ctx.Channel.EmbedAsync(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField("ID", userId.ToString(), true));
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField("ID", userId.ToString(), true));
|
||||
}
|
||||
else
|
||||
await Ban(user, msg);
|
||||
|
@ -500,7 +504,7 @@ public partial class Administration
|
|||
var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg));
|
||||
var embed = await _service.GetBanUserDmEmbed(Context, user, defaultMessage, msg, null);
|
||||
if (embed is not null)
|
||||
await user.SendAsync(embed);
|
||||
await Response().User(user).Text(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -511,10 +515,10 @@ public partial class Administration
|
|||
await ctx.Guild.AddBanAsync(user, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
||||
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
.WithOkColor()
|
||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
|
||||
if (dmFailed)
|
||||
toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -594,19 +598,19 @@ public partial class Administration
|
|||
private async Task InternalBanMessageTest(string reason, TimeSpan? duration)
|
||||
{
|
||||
var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), reason));
|
||||
var embed = await _service.GetBanUserDmEmbed(Context,
|
||||
var smartText = await _service.GetBanUserDmEmbed(Context,
|
||||
(IGuildUser)ctx.User,
|
||||
defaultMessage,
|
||||
reason,
|
||||
duration);
|
||||
|
||||
if (embed is null)
|
||||
if (smartText is null)
|
||||
await Response().Confirm(strs.banmsg_disabled).SendAsync();
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
await ctx.User.SendAsync(embed);
|
||||
await Response().User(ctx.User).Text(smartText).SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -692,7 +696,7 @@ public partial class Administration
|
|||
{
|
||||
await Response()
|
||||
.Channel(await user.CreateDMChannelAsync())
|
||||
.Error(GetText(strs.sbdm(Format.Bold(ctx.Guild.Name), msg)))
|
||||
.Error(strs.sbdm(Format.Bold(ctx.Guild.Name), msg))
|
||||
.SendAsync();
|
||||
}
|
||||
catch
|
||||
|
@ -706,10 +710,10 @@ public partial class Administration
|
|||
catch { await ctx.Guild.RemoveBanAsync(user); }
|
||||
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("☣ " + GetText(strs.sb_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
.WithOkColor()
|
||||
.WithTitle("☣ " + GetText(strs.sb_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
|
||||
if (dmFailed)
|
||||
toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -761,10 +765,10 @@ public partial class Administration
|
|||
await user.KickAsync((ctx.User + " | " + msg).TrimTo(512));
|
||||
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.kicked_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.kicked_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
|
||||
if (dmFailed)
|
||||
toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -792,9 +796,11 @@ public partial class Administration
|
|||
try
|
||||
{
|
||||
var dmMessage = GetText(strs.timeoutdm(Format.Bold(ctx.Guild.Name), msg));
|
||||
await user.EmbedAsync(new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithDescription(dmMessage));
|
||||
await _sender.Response(user)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithDescription(dmMessage))
|
||||
.SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -804,10 +810,10 @@ public partial class Administration
|
|||
await user.SetTimeOutAsync(time.Time);
|
||||
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("⏳ " + GetText(strs.timedout_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
.WithOkColor()
|
||||
.WithTitle("⏳ " + GetText(strs.timedout_user))
|
||||
.AddField(GetText(strs.username), user.ToString(), true)
|
||||
.AddField("ID", user.Id.ToString(), true);
|
||||
|
||||
if (dmFailed)
|
||||
toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||
|
@ -865,9 +871,9 @@ public partial class Administration
|
|||
missStr = "-";
|
||||
|
||||
var toSend = new EmbedBuilder()
|
||||
.WithDescription(GetText(strs.mass_ban_in_progress(banning.Count)))
|
||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||
.WithPendingColor();
|
||||
.WithDescription(GetText(strs.mass_ban_in_progress(banning.Count)))
|
||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||
.WithPendingColor();
|
||||
|
||||
var banningMessage = await Response().Embed(toSend).SendAsync();
|
||||
|
||||
|
@ -885,11 +891,11 @@ public partial class Administration
|
|||
}
|
||||
|
||||
await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
||||
.WithDescription(
|
||||
GetText(strs.mass_ban_completed(banning.Count())))
|
||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||
.WithOkColor()
|
||||
.Build());
|
||||
.WithDescription(
|
||||
GetText(strs.mass_ban_completed(banning.Count())))
|
||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||
.WithOkColor()
|
||||
.Build());
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -910,10 +916,10 @@ public partial class Administration
|
|||
|
||||
//send a message but don't wait for it
|
||||
var banningMessageTask = ctx.Channel.EmbedAsync(new EmbedBuilder()
|
||||
.WithDescription(
|
||||
GetText(strs.mass_kill_in_progress(bans.Count())))
|
||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||
.WithPendingColor());
|
||||
.WithDescription(
|
||||
GetText(strs.mass_kill_in_progress(bans.Count())))
|
||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||
.WithPendingColor());
|
||||
|
||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||
//do the banning
|
||||
|
@ -930,11 +936,11 @@ public partial class Administration
|
|||
var banningMessage = await banningMessageTask;
|
||||
|
||||
await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
||||
.WithDescription(
|
||||
GetText(strs.mass_kill_completed(bans.Count())))
|
||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||
.WithOkColor()
|
||||
.Build());
|
||||
.WithDescription(
|
||||
GetText(strs.mass_kill_completed(bans.Count())))
|
||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||
.WithOkColor()
|
||||
.Build());
|
||||
}
|
||||
|
||||
public class WarnExpireOptions : INadekoCommandOptions
|
||||
|
|
|
@ -71,7 +71,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
private readonly IBotStrings _strings;
|
||||
private readonly IBot _bot;
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly Random _rng;
|
||||
|
||||
|
@ -85,7 +85,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
DiscordSocketClient client,
|
||||
ICommandHandler cmd,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
IReplacementService repSvc,
|
||||
IPermissionChecker permChecker)
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
_strings = strings;
|
||||
_bot = bot;
|
||||
_pubSub = pubSub;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_repSvc = repSvc;
|
||||
_permChecker = permChecker;
|
||||
_rng = new NadekoRandom();
|
||||
|
@ -265,8 +265,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
|
||||
try
|
||||
{
|
||||
await msg.Channel
|
||||
.Response(_strings, _eb)
|
||||
await _sender.Response(msg.Channel)
|
||||
.Error(permissionMessage)
|
||||
.SendAsync();
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ public partial class Gambling
|
|||
}
|
||||
else
|
||||
await Response()
|
||||
.Confirm(GetText(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon)))
|
||||
.Confirm(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon))
|
||||
.SendAsync();
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
|
|
|
@ -65,7 +65,7 @@ public partial class Gambling
|
|||
|
||||
try
|
||||
{
|
||||
await ctx.User.EmbedAsync(eb);
|
||||
await Response().User(ctx.User).Embed(eb).SendAsync();
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -109,7 +109,7 @@ public partial class Gambling
|
|||
RepostCounter++;
|
||||
if (RepostCounter == 0)
|
||||
{
|
||||
try { msg = await ctx.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()); }
|
||||
try { msg = await Response().Embed(msg.Embeds.First().ToEmbedBuilder()).SendAsync(); }
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@ public class CurrencyEventsService : INService
|
|||
private readonly GamblingConfigService _configService;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, ICurrencyEvent> _events = new();
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public CurrencyEventsService(DiscordSocketClient client, ICurrencyService cs, GamblingConfigService configService)
|
||||
public CurrencyEventsService(DiscordSocketClient client, ICurrencyService cs, GamblingConfigService configService,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_client = client;
|
||||
_cs = cs;
|
||||
_configService = configService;
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
public async Task<bool> TryCreateEventAsync(
|
||||
|
@ -34,9 +37,9 @@ public class CurrencyEventsService : INService
|
|||
ICurrencyEvent ce;
|
||||
|
||||
if (type == CurrencyEvent.Type.Reaction)
|
||||
ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, embed);
|
||||
ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, _sender, embed);
|
||||
else if (type == CurrencyEvent.Type.GameStatus)
|
||||
ce = new GameStatusEvent(_client, _cs, g, ch, opts, embed);
|
||||
ce = new GameStatusEvent(_client, _cs, g, ch, opts, _sender, embed);
|
||||
else
|
||||
return false;
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||
private readonly object _stopLock = new();
|
||||
|
||||
private readonly object _potLock = new();
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public GameStatusEvent(
|
||||
DiscordSocketClient client,
|
||||
|
@ -43,6 +44,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||
SocketGuild g,
|
||||
ITextChannel ch,
|
||||
EventOptions opt,
|
||||
IMessageSenderService sender,
|
||||
Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embedFunc)
|
||||
{
|
||||
_client = client;
|
||||
|
@ -54,6 +56,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||
_isPotLimited = PotSize > 0;
|
||||
_channel = ch;
|
||||
_opts = opt;
|
||||
_sender = sender;
|
||||
// generate code
|
||||
_code = new(_sneakyGameStatusChars.Shuffle().Take(5).ToArray());
|
||||
|
||||
|
@ -106,7 +109,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||
|
||||
public async Task StartEvent()
|
||||
{
|
||||
msg = await _channel.EmbedAsync(GetEmbed(_opts.PotSize));
|
||||
msg = await _sender.Response(_channel).Embed(GetEmbed(_opts.PotSize)).SendAsync();
|
||||
await _client.SetGameAsync(_code);
|
||||
_client.MessageDeleted += OnMessageDeleted;
|
||||
_client.MessageReceived += HandleMessage;
|
||||
|
|
|
@ -30,6 +30,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||
private readonly object _stopLock = new();
|
||||
|
||||
private readonly object _potLock = new();
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public ReactionEvent(
|
||||
DiscordSocketClient client,
|
||||
|
@ -38,6 +39,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||
ITextChannel ch,
|
||||
EventOptions opt,
|
||||
GamblingConfig config,
|
||||
IMessageSenderService sender,
|
||||
Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embedFunc)
|
||||
{
|
||||
_client = client;
|
||||
|
@ -51,6 +53,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||
_noRecentlyJoinedServer = false;
|
||||
_opts = opt;
|
||||
_config = config;
|
||||
_sender = sender;
|
||||
|
||||
_t = new(OnTimerTick, null, Timeout.InfiniteTimeSpan, TimeSpan.FromSeconds(2));
|
||||
if (_opts.Hours > 0)
|
||||
|
@ -102,7 +105,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||
emote = parsedEmote;
|
||||
else
|
||||
emote = new Emoji(_config.Currency.Sign);
|
||||
msg = await _channel.EmbedAsync(GetEmbed(_opts.PotSize));
|
||||
msg = await _sender.Response(_channel).Embed(GetEmbed(_opts.PotSize)).SendAsync();
|
||||
await msg.AddReactionAsync(emote);
|
||||
_client.MessageDeleted += OnMessageDeleted;
|
||||
_client.ReactionAdded += HandleReaction;
|
||||
|
|
|
@ -74,7 +74,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
var stats = await _gamblingTxTracker.GetAllAsync();
|
||||
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor();
|
||||
.WithOkColor();
|
||||
|
||||
var str = "` Feature `|` Bet `|`Paid Out`|` RoI `\n";
|
||||
str += "――――――――――――――――――――\n";
|
||||
|
@ -119,15 +119,15 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
|
||||
// [21:03] Bob Page: Kinda remids me of US economy
|
||||
var embed = new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.economy_state))
|
||||
.AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot))
|
||||
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
||||
.AddField(GetText(strs.currency_planted), N(ec.Planted))
|
||||
.AddField(GetText(strs.owned_waifus_total), N(ec.Waifus))
|
||||
.AddField(GetText(strs.bot_currency), N(ec.Bot))
|
||||
.AddField(GetText(strs.bank_accounts), N(ec.Bank))
|
||||
.AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank))
|
||||
.WithOkColor();
|
||||
.WithTitle(GetText(strs.economy_state))
|
||||
.AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot))
|
||||
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
||||
.AddField(GetText(strs.currency_planted), N(ec.Planted))
|
||||
.AddField(GetText(strs.owned_waifus_total), N(ec.Waifus))
|
||||
.AddField(GetText(strs.bot_currency), N(ec.Bot))
|
||||
.AddField(GetText(strs.bank_accounts), N(ec.Bank))
|
||||
.AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank))
|
||||
.WithOkColor();
|
||||
|
||||
// ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table
|
||||
await Response().Embed(embed).SendAsync();
|
||||
|
@ -151,7 +151,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
GetText(strs.timely_time),
|
||||
ReminderType.Timely);
|
||||
|
||||
await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true);
|
||||
await smc.RespondConfirmAsync(_sender, GetText(strs.remind_timely(tt)), ephemeral: true);
|
||||
}
|
||||
|
||||
private NadekoInteraction CreateRemindMeInteraction(int period)
|
||||
|
@ -311,9 +311,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
}
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString()
|
||||
?? $"{userId}")))
|
||||
.WithOkColor();
|
||||
.WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString()
|
||||
?? $"{userId}")))
|
||||
.WithOkColor();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (var tr in trs)
|
||||
|
@ -415,7 +415,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
await N(balance)
|
||||
.Pipe(strs.bank_balance)
|
||||
.Pipe(GetText)
|
||||
.Pipe(text => smc.RespondConfirmAsync(_eb, text, ephemeral: true));
|
||||
.Pipe(text => smc.RespondConfirmAsync(_sender, text, ephemeral: true));
|
||||
}
|
||||
|
||||
private NadekoInteraction CreateCashInteraction()
|
||||
|
@ -460,7 +460,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
return;
|
||||
}
|
||||
|
||||
if (!await _cs.TransferAsync(_eb, ctx.User, receiver, amount, msg, N(amount)))
|
||||
if (!await _cs.TransferAsync(_sender, ctx.User, receiver, amount, msg, N(amount)))
|
||||
{
|
||||
await Response().Error(strs.not_enough(CurrencySign)).SendAsync();
|
||||
return;
|
||||
|
@ -732,10 +732,10 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
}
|
||||
|
||||
var eb = new EmbedBuilder()
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(Format.Bold(str))
|
||||
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
|
||||
.WithOkColor();
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(Format.Bold(str))
|
||||
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
|
||||
.WithOkColor();
|
||||
|
||||
await Response().Embed(eb).SendAsync();
|
||||
}
|
||||
|
@ -923,11 +923,11 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||
}
|
||||
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithDescription(sb.ToString())
|
||||
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
|
||||
.AddField(GetText(strs.won), $"{(long)result.Won}", true)
|
||||
.WithAuthor(ctx.User);
|
||||
.WithOkColor()
|
||||
.WithDescription(sb.ToString())
|
||||
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
|
||||
.AddField(GetText(strs.won), $"{(long)result.Won}", true)
|
||||
.WithAuthor(ctx.User);
|
||||
|
||||
|
||||
await Response().Embed(eb).SendAsync();
|
||||
|
|
|
@ -46,8 +46,8 @@ public partial class Gambling
|
|||
|
||||
using var uow = _db.GetDbContext();
|
||||
var entries = uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
||||
.ShopEntries.ToIndexed();
|
||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
||||
.ShopEntries.ToIndexed();
|
||||
return ctx.SendPaginatedConfirmAsync(page,
|
||||
curPage =>
|
||||
{
|
||||
|
@ -116,7 +116,9 @@ public partial class Gambling
|
|||
var guser = (IGuildUser)ctx.User;
|
||||
if (!guser.RoleIds.Contains(reqRoleId))
|
||||
{
|
||||
await Response().Error(strs.shop_item_req_role_unfulfilled(Format.Bold(role.ToString()))).SendAsync();
|
||||
await Response()
|
||||
.Error(strs.shop_item_req_role_unfulfilled(Format.Bold(role.ToString())))
|
||||
.SendAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -178,17 +180,20 @@ public partial class Gambling
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
uow.Set<ShopEntryItem>().Remove(item);
|
||||
uow.SaveChanges();
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await ctx.User.EmbedAsync(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name)))
|
||||
.AddField(GetText(strs.item), item.Text)
|
||||
.AddField(GetText(strs.price), entry.Price.ToString(), true)
|
||||
.AddField(GetText(strs.name), entry.Name, true));
|
||||
await Response()
|
||||
.User(ctx.User)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name)))
|
||||
.AddField(GetText(strs.item), item.Text)
|
||||
.AddField(GetText(strs.price), entry.Price.ToString(), true)
|
||||
.AddField(GetText(strs.name), entry.Name, true))
|
||||
.SendAsync();
|
||||
|
||||
await _cs.AddAsync(entry.AuthorId,
|
||||
GetProfitAmount(entry.Price),
|
||||
|
@ -200,9 +205,9 @@ public partial class Gambling
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
entry = entries.ElementAtOrDefault(index);
|
||||
if (entry is not null)
|
||||
{
|
||||
|
@ -242,16 +247,16 @@ public partial class Gambling
|
|||
{
|
||||
var cmd = entry.Command.Replace("%you%", ctx.User.Id.ToString());
|
||||
var eb = new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithTitle("Executing shop command")
|
||||
.WithDescription(cmd);
|
||||
.WithPendingColor()
|
||||
.WithTitle("Executing shop command")
|
||||
.WithDescription(cmd);
|
||||
|
||||
var msgTask = Response().Embed(eb).SendAsync();
|
||||
|
||||
await _cs.AddAsync(entry.AuthorId,
|
||||
GetProfitAmount(entry.Price),
|
||||
new("shop", "sell", entry.Name));
|
||||
|
||||
|
||||
await _cmdHandler.TryRunCommand(guild,
|
||||
channel,
|
||||
new DoAsUserMessage(
|
||||
|
@ -264,9 +269,9 @@ public partial class Gambling
|
|||
{
|
||||
var pendingMsg = await msgTask;
|
||||
await pendingMsg.EditAsync(SmartEmbedText.FromEmbed(eb
|
||||
.WithOkColor()
|
||||
.WithTitle("Shop command executed")
|
||||
.Build()));
|
||||
.WithOkColor()
|
||||
.WithTitle("Shop command executed")
|
||||
.Build()));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -314,9 +319,9 @@ public partial class Gambling
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
{
|
||||
entry
|
||||
};
|
||||
|
@ -346,9 +351,9 @@ public partial class Gambling
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
{
|
||||
entry
|
||||
};
|
||||
|
@ -377,9 +382,9 @@ public partial class Gambling
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
entry = entries.ElementAtOrDefault(index);
|
||||
if (entry is not null && (rightType = entry.Type == ShopEntryType.List))
|
||||
{
|
||||
|
@ -531,27 +536,27 @@ public partial class Gambling
|
|||
if (entry.Type == ShopEntryType.Role)
|
||||
{
|
||||
return embed
|
||||
.AddField(GetText(strs.name),
|
||||
GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name
|
||||
?? "MISSING_ROLE"))),
|
||||
true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||
.AddField(GetText(strs.name),
|
||||
GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name
|
||||
?? "MISSING_ROLE"))),
|
||||
true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||
}
|
||||
|
||||
if (entry.Type == ShopEntryType.List)
|
||||
{
|
||||
return embed.AddField(GetText(strs.name), entry.Name, true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
||||
}
|
||||
|
||||
|
||||
else if (entry.Type == ShopEntryType.Command)
|
||||
{
|
||||
return embed
|
||||
.AddField(GetText(strs.name), Format.Code(entry.Command), true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||
.AddField(GetText(strs.name), Format.Code(entry.Command), true)
|
||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||
}
|
||||
|
||||
//else if (entry.Type == ShopEntryType.Infinite_List)
|
||||
|
|
|
@ -20,9 +20,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
private readonly DiscordSocketClient _client;
|
||||
private readonly IPermissionChecker _perms;
|
||||
private readonly CommandHandler _cmd;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IPatronageService _ps;
|
||||
private readonly GamesConfigService _gcs;
|
||||
|
@ -33,10 +31,8 @@ public class ChatterBotService : IExecOnMessage
|
|||
IPermissionChecker perms,
|
||||
IBot bot,
|
||||
CommandHandler cmd,
|
||||
IBotStrings strings,
|
||||
IHttpClientFactory factory,
|
||||
IBotCredentials creds,
|
||||
IEmbedBuilderService eb,
|
||||
IPatronageService ps,
|
||||
GamesConfigService gcs,
|
||||
IMessageSenderService sender)
|
||||
|
@ -44,14 +40,12 @@ public class ChatterBotService : IExecOnMessage
|
|||
_client = client;
|
||||
_perms = perms;
|
||||
_cmd = cmd;
|
||||
_strings = strings;
|
||||
_creds = creds;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_httpFactory = factory;
|
||||
_ps = ps;
|
||||
_perms = perms;
|
||||
_gcs = gcs;
|
||||
_sender = sender;
|
||||
|
||||
_flKey = new FeatureLimitKey()
|
||||
{
|
||||
|
@ -166,8 +160,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
{
|
||||
if (ql.Quota == 0)
|
||||
{
|
||||
await channel
|
||||
.Response(_strings, _eb)
|
||||
await _sender.Response(channel)
|
||||
.Error(null,
|
||||
text:
|
||||
"In order to use the cleverbot feature, the owner of this server should be [Patron Tier X](https://patreon.com/join/nadekobot) on patreon.",
|
||||
|
@ -178,7 +171,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
return true;
|
||||
}
|
||||
|
||||
await channel.Response(_strings, _eb)
|
||||
await _sender.Response(channel)
|
||||
.Error(
|
||||
null!,
|
||||
$"You've reached your quota limit of **{ql.Quota}** responses {ql.QuotaPeriod.ToFullName()} for the cleverbot feature.",
|
||||
|
|
|
@ -23,7 +23,7 @@ public partial class Games
|
|||
/-\
|
||||
""";
|
||||
|
||||
public static EmbedBuilder GetEmbed(IEmbedBuilderService eb, HangmanGame.State state)
|
||||
public static EmbedBuilder GetEmbed(HangmanGame.State state)
|
||||
{
|
||||
if (state.Phase == HangmanGame.Phase.Running)
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ public partial class Games
|
|||
return;
|
||||
}
|
||||
|
||||
var eb = GetEmbed(_eb, hangman);
|
||||
var eb = GetEmbed(hangman);
|
||||
eb.WithDescription(GetText(strs.hangman_game_started));
|
||||
await Response().Embed(eb).SendAsync();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
|
|||
{
|
||||
private readonly ConcurrentDictionary<ulong, HangmanGame> _hangmanGames = new();
|
||||
private readonly IHangmanSource _source;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly GamesConfigService _gcs;
|
||||
private readonly ICurrencyService _cs;
|
||||
private readonly IMemoryCache _cdCache;
|
||||
|
@ -17,13 +17,13 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
|
|||
|
||||
public HangmanService(
|
||||
IHangmanSource source,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
GamesConfigService gcs,
|
||||
ICurrencyService cs,
|
||||
IMemoryCache cdCache)
|
||||
{
|
||||
_source = source;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_gcs = gcs;
|
||||
_cs = cs;
|
||||
_cdCache = cdCache;
|
||||
|
@ -116,7 +116,7 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
|
|||
string content,
|
||||
HangmanGame.State state)
|
||||
{
|
||||
var embed = Games.HangmanCommands.GetEmbed(_eb, state);
|
||||
var embed = Games.HangmanCommands.GetEmbed(state);
|
||||
if (state.GuessResult == HangmanGame.GuessResult.Guess)
|
||||
embed.WithDescription($"{user} guessed the letter {content}!").WithOkColor();
|
||||
else if (state.GuessResult == HangmanGame.GuessResult.Incorrect && state.Failed)
|
||||
|
@ -131,6 +131,6 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
|
|||
if (!string.IsNullOrWhiteSpace(state.ImageUrl) && Uri.IsWellFormedUriString(state.ImageUrl, UriKind.Absolute))
|
||||
embed.WithImageUrl(state.ImageUrl);
|
||||
|
||||
return channel.EmbedAsync(embed);
|
||||
return _sender.Response(channel).Embed(embed).SendAsync();
|
||||
}
|
||||
}
|
|
@ -78,10 +78,11 @@ public class TypingGame
|
|||
|
||||
var time = _options.StartTime;
|
||||
|
||||
var msg = await Channel.SendMessageAsync($"Starting new typing contest in **{time}**...");
|
||||
var msg = await _sender.Response(Channel).Confirm($"Starting new typing contest in **{time}**...").SendAsync();
|
||||
|
||||
do
|
||||
{
|
||||
// todo fix all modifies
|
||||
await Task.Delay(2000);
|
||||
time -= 2;
|
||||
try { await msg.ModifyAsync(m => m.Content = $"Starting new typing contest in **{time}**.."); }
|
||||
|
@ -144,13 +145,15 @@ public class TypingGame
|
|||
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
|
||||
_finishedUserIds.Add(msg.Author.Id);
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle($"{msg.Author} finished the race!")
|
||||
.AddField("Place", $"#{_finishedUserIds.Count}", true)
|
||||
.AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true)
|
||||
.AddField("Errors", distance.ToString(), true);
|
||||
|
||||
await _sender.Response(Channel)
|
||||
.Embed(eb => new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle($"{msg.Author} finished the race!")
|
||||
.AddField("Place", $"#{_finishedUserIds.Count}", true)
|
||||
.AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true)
|
||||
.AddField("Errors", distance.ToString(), true))
|
||||
.Embed(embed)
|
||||
.SendAsync();
|
||||
|
||||
if (_finishedUserIds.Count % 4 == 0)
|
||||
|
|
|
@ -26,7 +26,7 @@ public class TicTacToe
|
|||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly Options _options;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public TicTacToe(
|
||||
IBotStrings strings,
|
||||
|
@ -34,13 +34,13 @@ public class TicTacToe
|
|||
ITextChannel channel,
|
||||
IGuildUser firstUser,
|
||||
Options options,
|
||||
IEmbedBuilderService eb)
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_channel = channel;
|
||||
_strings = strings;
|
||||
_client = client;
|
||||
_options = options;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
_users = new[] { firstUser, null };
|
||||
_state = new int?[,] { { null, null, null }, { null, null, null }, { null, null, null } };
|
||||
|
@ -115,13 +115,13 @@ public class TicTacToe
|
|||
{
|
||||
if (phase is Phase.Started or Phase.Ended)
|
||||
{
|
||||
await _channel.Response(_strings, _eb).Error(user.Mention + GetText(strs.ttt_already_running)).SendAsync();
|
||||
await _sender.Response(_channel).Error(user.Mention + GetText(strs.ttt_already_running)).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_users[0] == user)
|
||||
{
|
||||
await _channel.Response(_strings, _eb).Error(user.Mention + GetText(strs.ttt_against_yourself)).SendAsync();
|
||||
await _sender.Response(_channel).Error(user.Mention + GetText(strs.ttt_against_yourself)).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ public class TicTacToe
|
|||
var del = previousMessage?.DeleteAsync();
|
||||
try
|
||||
{
|
||||
await _channel.EmbedAsync(GetEmbed(GetText(strs.ttt_time_expired)));
|
||||
await _sender.Response(_channel).Embed(GetEmbed(GetText(strs.ttt_time_expired))).SendAsync();
|
||||
if (del is not null)
|
||||
await del;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ public class TicTacToe
|
|||
_client.MessageReceived += Client_MessageReceived;
|
||||
|
||||
|
||||
previousMessage = await _channel.EmbedAsync(GetEmbed(GetText(strs.game_started)));
|
||||
previousMessage = await _sender.Response(_channel).Embed(GetEmbed(GetText(strs.game_started))).SendAsync();
|
||||
}
|
||||
|
||||
private bool IsDraw()
|
||||
|
@ -259,7 +259,7 @@ public class TicTacToe
|
|||
{
|
||||
var del1 = msg.DeleteAsync();
|
||||
var del2 = previousMessage?.DeleteAsync();
|
||||
try { previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); }
|
||||
try { previousMessage = await _sender.Response(_channel).Embed(GetEmbed(reason)).SendAsync(); }
|
||||
catch { }
|
||||
|
||||
try { await del1; }
|
||||
|
|
|
@ -35,7 +35,7 @@ public partial class Games
|
|||
return;
|
||||
}
|
||||
|
||||
game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _eb);
|
||||
game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _sender);
|
||||
_service.TicTacToeGames.Add(channel.Id, game);
|
||||
await Response().Confirm(strs.ttt_created).SendAsync();
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public partial class Games
|
|||
|
||||
if (_service.RunningTrivias.TryGetValue(ctx.Guild.Id, out var tg))
|
||||
{
|
||||
await Response().Error(GetText(strs.trivia_already_running)).SendAsync();
|
||||
await Response().Error(strs.trivia_already_running).SendAsync();
|
||||
await tg.TriggerQuestionAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -376,7 +376,7 @@ public sealed class Help : NadekoModule<HelpService>
|
|||
}
|
||||
|
||||
var embed = _cus.GetCommandHelp(com, ctx.Guild);
|
||||
await channel.EmbedAsync(embed);
|
||||
await _sender.Response(channel).Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -510,7 +510,7 @@ public sealed class Help : NadekoModule<HelpService>
|
|||
|
||||
|
||||
private Task SelfhostAction(SocketMessageComponent smc, object _)
|
||||
=> smc.RespondConfirmAsync(_eb,
|
||||
=> smc.RespondConfirmAsync(_sender,
|
||||
"""
|
||||
- In case you don't want or cannot Donate to NadekoBot project, but you
|
||||
- NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own "selfhosted" instance on your computer or server for free.
|
||||
|
|
|
@ -51,10 +51,10 @@ public sealed partial class Music
|
|||
}
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL)
|
||||
.WithDescription(string.Join("\n",
|
||||
playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count)))))
|
||||
.WithOkColor();
|
||||
.WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL)
|
||||
.WithDescription(string.Join("\n",
|
||||
playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count)))))
|
||||
.WithOkColor();
|
||||
|
||||
await Response().Embed(embed).SendAsync();
|
||||
}
|
||||
|
@ -111,7 +111,9 @@ public sealed partial class Music
|
|||
mpl.Songs.Skip(cur * 20)
|
||||
.Take(20)
|
||||
.Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
|
||||
return new EmbedBuilder().WithTitle($"\"{mpl.Name}\" by {mpl.Author}").WithOkColor().WithDescription(str);
|
||||
return new EmbedBuilder().WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
|
||||
.WithOkColor()
|
||||
.WithDescription(str);
|
||||
},
|
||||
mpl.Songs.Count,
|
||||
20);
|
||||
|
@ -151,11 +153,13 @@ public sealed partial class Music
|
|||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await Response().Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.playlist_saved))
|
||||
.AddField(GetText(strs.name), name)
|
||||
.AddField(GetText(strs.id), playlist.Id.ToString())).SendAsync();
|
||||
await Response()
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.playlist_saved))
|
||||
.AddField(GetText(strs.name), name)
|
||||
.AddField(GetText(strs.id), playlist.Id.ToString()))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -208,8 +212,9 @@ public sealed partial class Music
|
|||
IUserMessage msg = null;
|
||||
try
|
||||
{
|
||||
msg = await ctx.Channel.SendMessageAsync(
|
||||
GetText(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString()))));
|
||||
msg = await Response()
|
||||
.Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString())))
|
||||
.SendAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ public sealed class MusicService : IMusicService
|
|||
private readonly IBotStrings _strings;
|
||||
private readonly IGoogleApiService _googleApiService;
|
||||
private readonly YtLoader _ytLoader;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, IMusicPlayer> _players;
|
||||
private readonly ConcurrentDictionary<ulong, (ITextChannel Default, ITextChannel? Override)> _outputChannels;
|
||||
|
@ -31,7 +31,7 @@ public sealed class MusicService : IMusicService
|
|||
IBotStrings strings,
|
||||
IGoogleApiService googleApiService,
|
||||
YtLoader ytLoader,
|
||||
IEmbedBuilderService eb)
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_voiceStateService = voiceStateService;
|
||||
_trackResolveProvider = trackResolveProvider;
|
||||
|
@ -42,7 +42,7 @@ public sealed class MusicService : IMusicService
|
|||
_strings = strings;
|
||||
_googleApiService = googleApiService;
|
||||
_ytLoader = ytLoader;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
_players = new();
|
||||
_outputChannels = new ConcurrentDictionary<ulong, (ITextChannel, ITextChannel?)>();
|
||||
|
|
|
@ -13,7 +13,7 @@ public sealed class CurrencyRewardService : INService, IDisposable
|
|||
private readonly ICurrencyService _cs;
|
||||
private readonly IPatronageService _ps;
|
||||
private readonly DbService _db;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly GamblingConfigService _config;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
|
@ -21,14 +21,14 @@ public sealed class CurrencyRewardService : INService, IDisposable
|
|||
ICurrencyService cs,
|
||||
IPatronageService ps,
|
||||
DbService db,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
GamblingConfigService config,
|
||||
DiscordSocketClient client)
|
||||
{
|
||||
_cs = cs;
|
||||
_ps = ps;
|
||||
_db = db;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_config = config;
|
||||
_client = client;
|
||||
|
||||
|
@ -175,7 +175,7 @@ public sealed class CurrencyRewardService : INService, IDisposable
|
|||
.WithOkColor()
|
||||
.WithDescription(message);
|
||||
|
||||
await user.EmbedAsync(eb);
|
||||
await _sender.Response(user).Embed(eb).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -31,10 +31,12 @@ public partial class Patronage : NadekoModule
|
|||
_ = ctx.Channel.TriggerTypingAsync();
|
||||
var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message);
|
||||
|
||||
await Response().Confirm(strs.patron_msg_sent(
|
||||
Format.Code(tierAndHigher.ToString()),
|
||||
Format.Bold(result.Success.ToString()),
|
||||
Format.Bold(result.Failed.ToString()))).SendAsync();
|
||||
await Response()
|
||||
.Confirm(strs.patron_msg_sent(
|
||||
Format.Code(tierAndHigher.ToString()),
|
||||
Format.Bold(result.Success.ToString()),
|
||||
Format.Bold(result.Failed.ToString())))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
// [OwnerOnly]
|
||||
|
@ -69,9 +71,9 @@ public partial class Patronage : NadekoModule
|
|||
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
|
||||
|
||||
var eb = new EmbedBuilder()
|
||||
.WithAuthor(user)
|
||||
.WithTitle(GetText(strs.patron_info))
|
||||
.WithOkColor();
|
||||
.WithAuthor(user)
|
||||
.WithTitle(GetText(strs.patron_info))
|
||||
.WithOkColor();
|
||||
|
||||
if (quotaStats.Commands.Count == 0
|
||||
&& quotaStats.Groups.Count == 0
|
||||
|
@ -82,7 +84,7 @@ public partial class Patronage : NadekoModule
|
|||
else
|
||||
{
|
||||
eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true)
|
||||
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
|
||||
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
|
||||
|
||||
if (patron.Tier != PatronTier.None)
|
||||
eb.AddField(GetText(strs.expires), patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), true);
|
||||
|
@ -114,7 +116,7 @@ public partial class Patronage : NadekoModule
|
|||
|
||||
try
|
||||
{
|
||||
await ctx.User.EmbedAsync(eb);
|
||||
await Response().User(ctx.User).Embed(eb).SendAsync();
|
||||
_ = ctx.OkAsync();
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -29,7 +29,6 @@ public sealed class PatronageService
|
|||
private readonly DbService _db;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly ISubscriptionHandler _subsHandler;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
|
||||
private static readonly TypedKey<long> _quotaKey
|
||||
= new($"quota:last_hourly_reset");
|
||||
|
@ -43,7 +42,6 @@ public sealed class PatronageService
|
|||
DbService db,
|
||||
DiscordSocketClient client,
|
||||
ISubscriptionHandler subsHandler,
|
||||
IEmbedBuilderService eb,
|
||||
IBotCache cache,
|
||||
IBotCredsProvider creds,
|
||||
IMessageSenderService sender)
|
||||
|
@ -52,10 +50,9 @@ public sealed class PatronageService
|
|||
_db = db;
|
||||
_client = client;
|
||||
_subsHandler = subsHandler;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_cache = cache;
|
||||
_creds = creds;
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
public Task OnReadyAsync()
|
||||
|
@ -310,12 +307,12 @@ public sealed class PatronageService
|
|||
ins =>
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithTitle("Insufficient Patron Tier")
|
||||
.AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true)
|
||||
.AddField("Required Tier",
|
||||
$"[{ins.RequiredTier.ToFullName()}](https://patreon.com/join/nadekobot)",
|
||||
true);
|
||||
.WithPendingColor()
|
||||
.WithTitle("Insufficient Patron Tier")
|
||||
.AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true)
|
||||
.AddField("Required Tier",
|
||||
$"[{ins.RequiredTier.ToFullName()}](https://patreon.com/join/nadekobot)",
|
||||
true);
|
||||
|
||||
if (ctx.Guild is null || ctx.Guild?.OwnerId == ctx.User.Id)
|
||||
eb.WithDescription("You don't have the sufficent Patron Tier to run this command.")
|
||||
|
@ -333,15 +330,15 @@ public sealed class PatronageService
|
|||
.Embed(eb)
|
||||
.SendAsync();
|
||||
else
|
||||
_ = ctx.User.EmbedAsync(eb);
|
||||
_ = _sender.Response(ctx).User(ctx.User).Embed(eb).SendAsync();
|
||||
|
||||
return true;
|
||||
},
|
||||
quota =>
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithPendingColor()
|
||||
.WithTitle("Quota Limit Reached");
|
||||
.WithPendingColor()
|
||||
.WithTitle("Quota Limit Reached");
|
||||
|
||||
if (quota.IsOwnQuota || ctx.User.Id == ownerId)
|
||||
{
|
||||
|
@ -369,7 +366,7 @@ public sealed class PatronageService
|
|||
.Embed(eb)
|
||||
.SendAsync();
|
||||
else
|
||||
_ = ctx.User.EmbedAsync(eb);
|
||||
_ = _sender.Response(ctx).User(ctx.User).Embed(eb).SendAsync();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
@ -782,30 +779,30 @@ public sealed class PatronageService
|
|||
return;
|
||||
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("❤️ Thank you for supporting NadekoBot! ❤️")
|
||||
.WithDescription(
|
||||
"Your donation has been processed and you will receive the rewards shortly.\n"
|
||||
+ "You can visit <https://www.patreon.com/join/nadekobot> to see rewards for your tier. 🎉")
|
||||
.AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
|
||||
.AddField("Pledge", $"**{patron.Amount / 100.0f:N1}$**", true)
|
||||
.AddField("Expires",
|
||||
patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(),
|
||||
true)
|
||||
.AddField("Instructions",
|
||||
"""
|
||||
*- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.*
|
||||
*- You can check your benefits on <https://www.patreon.com/join/nadekobot>*
|
||||
*- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands*
|
||||
*- **ALL** of the servers that you **own** will enjoy your Patron benefits.*
|
||||
*- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)*
|
||||
*- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.*
|
||||
*- Permission guide can be found here if you're not familiar with it: <https://nadekobot.readthedocs.io/en/latest/permissions-system/>*
|
||||
""",
|
||||
inline: false)
|
||||
.WithFooter($"platform id: {patron.UniquePlatformUserId}");
|
||||
.WithOkColor()
|
||||
.WithTitle("❤️ Thank you for supporting NadekoBot! ❤️")
|
||||
.WithDescription(
|
||||
"Your donation has been processed and you will receive the rewards shortly.\n"
|
||||
+ "You can visit <https://www.patreon.com/join/nadekobot> to see rewards for your tier. 🎉")
|
||||
.AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
|
||||
.AddField("Pledge", $"**{patron.Amount / 100.0f:N1}$**", true)
|
||||
.AddField("Expires",
|
||||
patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(),
|
||||
true)
|
||||
.AddField("Instructions",
|
||||
"""
|
||||
*- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.*
|
||||
*- You can check your benefits on <https://www.patreon.com/join/nadekobot>*
|
||||
*- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands*
|
||||
*- **ALL** of the servers that you **own** will enjoy your Patron benefits.*
|
||||
*- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)*
|
||||
*- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.*
|
||||
*- Permission guide can be found here if you're not familiar with it: <https://nadekobot.readthedocs.io/en/latest/permissions-system/>*
|
||||
""",
|
||||
inline: false)
|
||||
.WithFooter($"platform id: {patron.UniquePlatformUserId}");
|
||||
|
||||
await user.EmbedAsync(eb);
|
||||
await _sender.Response(user).Embed(eb).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -830,7 +827,7 @@ public sealed class PatronageService
|
|||
try
|
||||
{
|
||||
var user = await _client.GetUserAsync(patron.UserId);
|
||||
await user.SendAsync(text);
|
||||
await _sender.Response(user).Text(text).SendAsync();
|
||||
++succ;
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -17,7 +17,6 @@ public class PermissionService : IExecPreCommand, INService
|
|||
private readonly DbService _db;
|
||||
private readonly CommandHandler _cmd;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public PermissionService(
|
||||
|
@ -25,13 +24,11 @@ public class PermissionService : IExecPreCommand, INService
|
|||
DbService db,
|
||||
CommandHandler cmd,
|
||||
IBotStrings strings,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_db = db;
|
||||
_cmd = cmd;
|
||||
_strings = strings;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
|
|
|
@ -6,7 +6,6 @@ using System.Text.Json;
|
|||
|
||||
namespace NadekoBot.Modules.Searches;
|
||||
|
||||
// todo fix stock
|
||||
public sealed class DefaultStockDataService : IStockDataService, INService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
|
|
@ -14,7 +14,7 @@ public class FeedsService : INService
|
|||
private readonly DbService _db;
|
||||
private readonly ConcurrentDictionary<string, List<FeedSub>> _subs;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
private readonly ConcurrentDictionary<string, DateTime> _lastPosts = new();
|
||||
private readonly Dictionary<string, uint> _errorCounters = new();
|
||||
|
@ -23,7 +23,7 @@ public class FeedsService : INService
|
|||
IBot bot,
|
||||
DbService db,
|
||||
DiscordSocketClient client,
|
||||
IEmbedBuilderService eb)
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_db = db;
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class FeedsService : INService
|
|||
}
|
||||
|
||||
_client = client;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
_ = Task.Run(TrackFeeds);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public partial class Searches
|
|||
}
|
||||
|
||||
memeUrl += ".png";
|
||||
await ctx.Channel.SendMessageAsync(memeUrl);
|
||||
await Response().Text(memeUrl).SendAsync();
|
||||
}
|
||||
|
||||
private static string Replace(string input)
|
||||
|
|
|
@ -165,7 +165,7 @@ public partial class Searches
|
|||
}
|
||||
|
||||
await AddYoutubeUrlToCacheAsync(query, result.Url);
|
||||
await ctx.Channel.SendMessageAsync(result.Url);
|
||||
await Response().Text(result.Url).SendAsync();
|
||||
}
|
||||
|
||||
// [Cmd]
|
||||
|
|
|
@ -141,7 +141,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||
.AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true)
|
||||
.AddField(GetText(strs.timezone), data.TimeZoneName, true);
|
||||
|
||||
await ctx.Channel.SendMessageAsync(embed: eb.Build());
|
||||
await Response().Embed(eb).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -441,7 +441,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||
if (data.Query.Pages[0].Missing || string.IsNullOrWhiteSpace(data.Query.Pages[0].FullUrl))
|
||||
await Response().Error(strs.wiki_page_not_found).SendAsync();
|
||||
else
|
||||
await ctx.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl);
|
||||
await Response().Text(data.Query.Pages[0].FullUrl).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -514,7 +514,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||
var url = Uri.EscapeDataString($"https://{target}.fandom.com/wiki/{title}");
|
||||
var response = $@"`{GetText(strs.title)}` {title.SanitizeMentions()}
|
||||
`{GetText(strs.url)}:` {url}";
|
||||
await ctx.Channel.SendMessageAsync(response);
|
||||
await Response().Text(response).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -575,7 +575,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||
// .AddField(GetText(strs.price), gameData.IsFree ? GetText(strs.FREE) : game, true)
|
||||
// .AddField(GetText(strs.links), gameData.GetGenresString(), true)
|
||||
// .WithFooter(GetText(strs.recommendations(gameData.TotalRecommendations)));
|
||||
await ctx.Channel.SendMessageAsync($"https://store.steampowered.com/app/{appId}");
|
||||
await Response().Text($"https://store.steampowered.com/app/{appId}").SendAsync();
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateQuery([MaybeNullWhen(false)] string query)
|
||||
|
|
|
@ -25,7 +25,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||
private readonly ConcurrentHashSet<ulong> _deleteOnOfflineServers;
|
||||
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly SearchesConfigService _config;
|
||||
private readonly IReplacementService _repSvc;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||
IHttpClientFactory httpFactory,
|
||||
IBot bot,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
SearchesConfigService config,
|
||||
IReplacementService repSvc)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||
_client = client;
|
||||
_strings = strings;
|
||||
_pubSub = pubSub;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_config = config;
|
||||
_repSvc = repSvc;
|
||||
|
||||
|
@ -285,7 +285,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||
? ""
|
||||
: await _repSvc.ReplaceAsync(fs.Message, repCtx);
|
||||
|
||||
var msg = await textChannel.EmbedAsync(GetEmbed(fs.GuildId, stream, false), message);
|
||||
var msg = await _sender.Response(textChannel)
|
||||
.Embed(GetEmbed(fs.GuildId, stream, false))
|
||||
.Text(message)
|
||||
.SendAsync();
|
||||
|
||||
// only cache the ids of channel/message pairs
|
||||
if (_deleteOnOfflineServers.Contains(fs.GuildId))
|
||||
|
|
|
@ -12,7 +12,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||
{
|
||||
private readonly IGoogleApiService _google;
|
||||
private readonly DbService _db;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly IBot _bot;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, bool> _atcs = new();
|
||||
|
@ -21,12 +21,12 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||
public TranslateService(
|
||||
IGoogleApiService google,
|
||||
DbService db,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
IBot bot)
|
||||
{
|
||||
_google = google;
|
||||
_db = db;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_bot = bot;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||
.AddField(langs.From, um.Content)
|
||||
.AddField(langs.To, output);
|
||||
|
||||
await tch.EmbedAsync(embed);
|
||||
await _sender.Response(tch).Embed(embed).SendAsync();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ public sealed class GiveawayService : INService, IReadyExecutor
|
|||
private readonly DbService _db;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly ILocalization _localization;
|
||||
private readonly IMemoryCache _cache;
|
||||
|
@ -22,12 +22,12 @@ public sealed class GiveawayService : INService, IReadyExecutor
|
|||
private readonly ConcurrentDictionary<int, GiveawayRerollData> _rerolls = new();
|
||||
|
||||
public GiveawayService(DbService db, IBotCredentials creds, DiscordSocketClient client,
|
||||
IEmbedBuilderService eb, IBotStrings strings, ILocalization localization, IMemoryCache cache)
|
||||
IMessageSenderService sender, IBotStrings strings, ILocalization localization, IMemoryCache cache)
|
||||
{
|
||||
_db = db;
|
||||
_creds = creds;
|
||||
_client = client;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_strings = strings;
|
||||
_localization = localization;
|
||||
_cache = cache;
|
||||
|
@ -317,8 +317,7 @@ public sealed class GiveawayService : INService, IReadyExecutor
|
|||
{Format.Code(winner.UserId.ToString())}
|
||||
""";
|
||||
|
||||
var eb = _eb
|
||||
.Create()
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.giveaway_ended))
|
||||
.WithDescription(ga.Message)
|
||||
|
@ -334,7 +333,7 @@ public sealed class GiveawayService : INService, IReadyExecutor
|
|||
catch
|
||||
{
|
||||
_ = msg.DeleteAsync();
|
||||
await ch.EmbedAsync(eb);
|
||||
await _sender.Response(ch).Embed(eb).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,23 +133,23 @@ public partial class Utility
|
|||
private async Task ShowQuoteData(Quote data)
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:")
|
||||
.WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096))
|
||||
.AddField(GetText(strs.trigger), data.Keyword)
|
||||
.WithFooter(
|
||||
GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})")))
|
||||
.Build();
|
||||
.WithOkColor()
|
||||
.WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:")
|
||||
.WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096))
|
||||
.AddField(GetText(strs.trigger), data.Keyword)
|
||||
.WithFooter(
|
||||
GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})")));
|
||||
|
||||
if (!(data.Text.Length > 4096))
|
||||
{
|
||||
await ctx.Channel.SendMessageAsync(embed: eb);
|
||||
await Response().Embed(eb).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// todo all send files should go through response system too
|
||||
await ctx.Channel.SendFileAsync(
|
||||
attachment: new FileAttachment(await data.Text.ToStream(), "quote.txt"),
|
||||
embed: eb);
|
||||
embed: eb.Build());
|
||||
}
|
||||
|
||||
private async Task QuoteSearchinternalAsync(string? keyword, string textOrAuthor)
|
||||
|
@ -168,10 +168,12 @@ public partial class Utility
|
|||
if (quote is null)
|
||||
return;
|
||||
|
||||
await ctx.Channel.SendMessageAsync($"`#{quote.Id}` 💬 "
|
||||
+ quote.Keyword.ToLowerInvariant()
|
||||
+ ": "
|
||||
+ quote.Text.SanitizeAllMentions());
|
||||
await Response()
|
||||
.Confirm($"`#{quote.Id}` 💬 ",
|
||||
quote.Keyword.ToLowerInvariant()
|
||||
+ ": "
|
||||
+ quote.Text.SanitizeAllMentions())
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -204,7 +206,7 @@ public partial class Utility
|
|||
|
||||
if (quote is null || quote.GuildId != ctx.Guild.Id)
|
||||
{
|
||||
await Response().Error(GetText(strs.quotes_notfound)).SendAsync();
|
||||
await Response().Error(strs.quotes_notfound).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,25 +11,26 @@ namespace NadekoBot.Modules.Utility.Services;
|
|||
public class RemindService : INService, IReadyExecutor, IRemindService
|
||||
{
|
||||
private readonly Regex _regex =
|
||||
new(@"^(?:(?:at|on(?:\sthe)?)?\s*(?<date>(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?<mo>\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?<w>\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?<d>\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?<h>\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?<m>\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?<what>(?:\r\n|[\r\n]|.)+)",
|
||||
new(
|
||||
@"^(?:(?:at|on(?:\sthe)?)?\s*(?<date>(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?<mo>\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?<w>\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?<d>\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?<h>\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?<m>\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?<what>(?:\r\n|[\r\n]|.)+)",
|
||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
|
||||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly DbService _db;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public RemindService(
|
||||
DiscordSocketClient client,
|
||||
DbService db,
|
||||
IBotCredentials creds,
|
||||
IEmbedBuilderService eb)
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
_client = client;
|
||||
_db = db;
|
||||
_creds = creds;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -120,7 +121,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||
if (!string.IsNullOrWhiteSpace(dateString))
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
|
||||
if (!DateTime.TryParse(dateString, _culture, DateTimeStyles.None, out var dt))
|
||||
{
|
||||
Log.Warning("Invalid remind datetime format");
|
||||
|
@ -162,6 +163,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||
|
||||
values[groupName] = value;
|
||||
}
|
||||
|
||||
ts = new TimeSpan((30 * values["mo"]) + (7 * values["w"]) + values["d"], values["h"], values["m"], 0);
|
||||
}
|
||||
|
||||
|
@ -197,22 +199,24 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||
|
||||
if (st is SmartEmbedText set)
|
||||
{
|
||||
await ch.SendMessageAsync(null, embed: set.GetEmbed().Build());
|
||||
await _sender.Response(ch).Embed(set.GetEmbed()).SendAsync();
|
||||
}
|
||||
else if (st is SmartEmbedTextArray seta)
|
||||
{
|
||||
await ch.SendMessageAsync(null, embeds: seta.GetEmbedBuilders().Map(x => x.Build()));
|
||||
await _sender.Response(ch).Embeds(seta.GetEmbedBuilders()).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await ch.EmbedAsync(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("Reminder")
|
||||
.AddField("Created At",
|
||||
r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?")
|
||||
.AddField("By",
|
||||
(await ch.GetUserAsync(r.UserId))?.ToString() ?? r.UserId.ToString()),
|
||||
r.Message);
|
||||
await _sender.Response(ch)
|
||||
.Embed(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("Reminder")
|
||||
.AddField("Created At",
|
||||
r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?")
|
||||
.AddField("By",
|
||||
(await ch.GetUserAsync(r.UserId))?.ToString() ?? r.UserId.ToString()))
|
||||
.Text(r.Message)
|
||||
.SendAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -227,7 +231,8 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||
public TimeSpan Time { get; set; }
|
||||
}
|
||||
|
||||
public async Task AddReminderAsync(ulong userId,
|
||||
public async Task AddReminderAsync(
|
||||
ulong userId,
|
||||
ulong targetId,
|
||||
ulong? guildId,
|
||||
bool isPrivate,
|
||||
|
@ -242,7 +247,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||
ServerId = guildId ?? 0,
|
||||
IsPrivate = isPrivate,
|
||||
When = time,
|
||||
Message = message,
|
||||
Message = message,
|
||||
Type = reminderType
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using NadekoBot.Db.Models;
|
||||
using System.Text;
|
||||
|
||||
namespace NadekoBot.Modules.Utility;
|
||||
|
||||
|
@ -86,8 +87,8 @@ public partial class Utility
|
|||
(curPage) =>
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.todo_list));
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.todo_list));
|
||||
|
||||
ShowTodoItem(todos, curPage, eb);
|
||||
|
||||
|
@ -99,15 +100,15 @@ public partial class Utility
|
|||
|
||||
private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, int curPage, EmbedBuilder eb)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var todo in todos.Skip(curPage * 9).Take(9))
|
||||
{
|
||||
// green circle and yellow circle emojis
|
||||
eb.AddField($"-",
|
||||
$"{(todo.IsDone
|
||||
? "✅"
|
||||
: "🟡")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}",
|
||||
false);
|
||||
sb.AppendLine($"{(todo.IsDone ? "✔" : "□")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}");
|
||||
|
||||
sb.AppendLine("---");
|
||||
}
|
||||
|
||||
eb.WithDescription(sb.ToString());
|
||||
}
|
||||
|
||||
[Group("archive")]
|
||||
|
@ -150,8 +151,8 @@ public partial class Utility
|
|||
(curPage) =>
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithTitle(GetText(strs.todo_archive_list))
|
||||
.WithOkColor();
|
||||
.WithTitle(GetText(strs.todo_archive_list))
|
||||
.WithOkColor();
|
||||
|
||||
foreach (var archivedList in archivedTodoLists.Skip(curPage * 9).Take(9))
|
||||
{
|
||||
|
@ -179,8 +180,8 @@ public partial class Utility
|
|||
(curPage) =>
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.todo_list));
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.todo_list));
|
||||
|
||||
ShowTodoItem(list.Items, curPage, eb);
|
||||
|
||||
|
|
|
@ -90,10 +90,10 @@ public partial class Utility
|
|||
res = Math.Round(res, 4);
|
||||
|
||||
await Response()
|
||||
.Confirm(GetText(strs.convert(value,
|
||||
.Confirm(strs.convert(value,
|
||||
originUnit.Triggers.Last(),
|
||||
res,
|
||||
targetUnit.Triggers.Last())))
|
||||
targetUnit.Triggers.Last()))
|
||||
.SendAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,7 +337,7 @@ public partial class Utility : NadekoModule
|
|||
if (string.IsNullOrWhiteSpace(result))
|
||||
await Response().Error(strs.showemojis_none).SendAsync();
|
||||
else
|
||||
await ctx.Channel.SendMessageAsync(result.TrimTo(2000));
|
||||
await Response().Text(result.TrimTo(2000)).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -613,7 +613,7 @@ public partial class Utility : NadekoModule
|
|||
try
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
var msg = await ctx.Channel.SendMessageAsync("🏓");
|
||||
var msg = await Response().Text("🏓").SendAsync();
|
||||
sw.Stop();
|
||||
msg.DeleteAfter(0);
|
||||
|
||||
|
|
|
@ -9,16 +9,19 @@ public class VerboseErrorsService : INService
|
|||
private readonly DbService _db;
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly ICommandsUtilityService _hs;
|
||||
private readonly IMessageSenderService _sender;
|
||||
|
||||
public VerboseErrorsService(
|
||||
IBot bot,
|
||||
DbService db,
|
||||
CommandHandler ch,
|
||||
IMessageSenderService sender,
|
||||
ICommandsUtilityService hs)
|
||||
{
|
||||
_db = db;
|
||||
_ch = ch;
|
||||
_hs = hs;
|
||||
_sender = sender;
|
||||
|
||||
_ch.CommandErrored += LogVerboseError;
|
||||
|
||||
|
@ -38,7 +41,7 @@ public class VerboseErrorsService : INService
|
|||
.WithFooter("Admin may disable verbose errors via `.ve` command")
|
||||
.WithErrorColor();
|
||||
|
||||
await channel.EmbedAsync(embed);
|
||||
await _sender.Response(channel).Embed(embed).SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -31,7 +31,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
|||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly XpConfigService _xpConfig;
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedRoles;
|
||||
private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedChannels;
|
||||
|
@ -62,7 +61,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
|||
IHttpClientFactory http,
|
||||
XpConfigService xpConfig,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb,
|
||||
IPatronageService ps,
|
||||
IMessageSenderService sender)
|
||||
{
|
||||
|
@ -75,14 +73,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
|||
_httpFactory = http;
|
||||
_xpConfig = xpConfig;
|
||||
_pubSub = pubSub;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_excludedServers = new();
|
||||
_excludedChannels = new();
|
||||
_client = client;
|
||||
_xpTemplateReloadKey = new("xp.template.reload");
|
||||
_ps = ps;
|
||||
_c = c;
|
||||
_sender = sender;
|
||||
|
||||
InternalReloadXpTemplate();
|
||||
|
||||
|
@ -393,11 +390,12 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
|||
{
|
||||
if (notifyLoc == XpNotificationLocation.Dm)
|
||||
{
|
||||
await user.SendConfirmAsync(_eb,
|
||||
_strings.GetText(strs.level_up_dm(user.Mention,
|
||||
Format.Bold(newLevel.ToString()),
|
||||
Format.Bold(guild.ToString() ?? "-")),
|
||||
guild.Id));
|
||||
await _sender.Response(user)
|
||||
.Confirm(_strings.GetText(strs.level_up_dm(user.Mention,
|
||||
Format.Bold(newLevel.ToString()),
|
||||
Format.Bold(guild.ToString() ?? "-")),
|
||||
guild.Id))
|
||||
.SendAsync();
|
||||
}
|
||||
else // channel
|
||||
{
|
||||
|
|
|
@ -8,20 +8,20 @@ public sealed class PermissionChecker : IPermissionChecker, INService
|
|||
private readonly PermissionService _perms;
|
||||
private readonly GlobalPermissionService _gperm;
|
||||
private readonly CmdCdService _cmdCds;
|
||||
private readonly IEmbedBuilderService _ebs;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly CommandHandler _ch;
|
||||
|
||||
public PermissionChecker(
|
||||
PermissionService perms,
|
||||
GlobalPermissionService gperm,
|
||||
CmdCdService cmdCds,
|
||||
IEmbedBuilderService ebs,
|
||||
IMessageSenderService sender,
|
||||
CommandHandler ch)
|
||||
{
|
||||
_perms = perms;
|
||||
_gperm = gperm;
|
||||
_cmdCds = cmdCds;
|
||||
_ebs = ebs;
|
||||
_sender = sender;
|
||||
_ch = ch;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ public enum LogType
|
|||
ChannelUpdated,
|
||||
UserPresence,
|
||||
VoicePresence,
|
||||
VoicePresenceTts,
|
||||
UserMuted,
|
||||
UserWarned,
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ public sealed class DmContextAdapter : DmContext
|
|||
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly Lazy<IEmbedBuilderService> _ebs;
|
||||
private readonly Lazy<IBotStrings> _botStrings;
|
||||
private readonly Lazy<ILocalization> _localization;
|
||||
|
||||
|
@ -32,14 +31,10 @@ public sealed class DmContextAdapter : DmContext
|
|||
Bot = ctx.Client.CurrentUser;
|
||||
|
||||
|
||||
_ebs = new(_services.GetRequiredService<IEmbedBuilderService>());
|
||||
_botStrings = new(_services.GetRequiredService<IBotStrings>);
|
||||
_localization = new(_services.GetRequiredService<ILocalization>());
|
||||
}
|
||||
|
||||
public override EmbedBuilder Embed()
|
||||
=> new EmbedBuilder();
|
||||
|
||||
public override string GetText(string key, object[]? args = null)
|
||||
{
|
||||
var cultureInfo = _localization.Value.GetCultureInfo(default(ulong?));
|
||||
|
|
|
@ -5,7 +5,6 @@ public sealed class GuildContextAdapter : GuildContext
|
|||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ICommandContext _ctx;
|
||||
private readonly Lazy<IEmbedBuilderService> _ebs;
|
||||
private readonly Lazy<IBotStrings> _botStrings;
|
||||
private readonly Lazy<ILocalization> _localization;
|
||||
|
||||
|
@ -18,9 +17,6 @@ public sealed class GuildContextAdapter : GuildContext
|
|||
|
||||
public override IGuildUser User { get; }
|
||||
|
||||
public override EmbedBuilder Embed()
|
||||
=> _ebs.Value.Create();
|
||||
|
||||
public GuildContextAdapter(ICommandContext ctx, IMedusaStrings strings, IServiceProvider services)
|
||||
{
|
||||
if (ctx.Guild is not IGuild guild || ctx.Channel is not ITextChannel channel)
|
||||
|
@ -33,7 +29,6 @@ public sealed class GuildContextAdapter : GuildContext
|
|||
Bot = ctx.Client.CurrentUser;
|
||||
|
||||
_services = services;
|
||||
_ebs = new(_services.GetRequiredService<IEmbedBuilderService>());
|
||||
_botStrings = new(_services.GetRequiredService<IBotStrings>);
|
||||
_localization = new(_services.GetRequiredService<ILocalization>());
|
||||
|
||||
|
|
|
@ -342,7 +342,6 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
|||
var sis = LoadSneksFromAssembly(safeName, a);
|
||||
typeReaders = LoadTypeReadersFromAssembly(a, strings);
|
||||
|
||||
// todo allow this
|
||||
if (sis.Count == 0)
|
||||
{
|
||||
_kernel.Unload(safeName);
|
||||
|
|
|
@ -16,7 +16,6 @@ public abstract class NadekoModule : ModuleBase
|
|||
public IBotStrings Strings { get; set; }
|
||||
public ICommandHandler _cmdHandler { get; set; }
|
||||
public ILocalization _localization { get; set; }
|
||||
public IEmbedBuilderService _eb { get; set; }
|
||||
public INadekoInteractionService _inter { get; set; }
|
||||
public IReplacementService repSvc { get; set; }
|
||||
public IMessageSenderService _sender { get; set; }
|
||||
|
@ -28,7 +27,7 @@ public abstract class NadekoModule : ModuleBase
|
|||
=> Context;
|
||||
|
||||
public ResponseBuilder Response()
|
||||
=> new ResponseBuilder(Strings, _eb)
|
||||
=> new ResponseBuilder(Strings)
|
||||
.Context(ctx);
|
||||
|
||||
protected override void BeforeExecute(CommandInfo command)
|
||||
|
|
|
@ -3,5 +3,8 @@
|
|||
public interface IMessageSenderService
|
||||
{
|
||||
ResponseBuilder Response(IMessageChannel channel);
|
||||
ResponseBuilder Response(ICommandContext hannel);
|
||||
ResponseBuilder Response(ICommandContext ctx);
|
||||
ResponseBuilder Response(IUser user);
|
||||
|
||||
ResponseBuilder Response(SocketMessageComponent smc);
|
||||
}
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
public static class MessageChannelExtensions
|
||||
{
|
||||
public static ResponseBuilder Response(this IMessageChannel channel, IBotStrings bs, IEmbedBuilderService ebs)
|
||||
=> new ResponseBuilder(bs, ebs)
|
||||
.Channel(channel);
|
||||
|
||||
// main overload that all other send methods reduce to
|
||||
public static Task<IUserMessage> SendAsync(
|
||||
this IMessageChannel channel,
|
||||
|
@ -92,7 +88,7 @@ public static class MessageChannelExtensions
|
|||
this IMessageChannel ch,
|
||||
EmbedBuilder? embed,
|
||||
string plainText = "",
|
||||
IReadOnlyCollection<IEmbedBuilder>? embeds = null,
|
||||
IReadOnlyCollection<EmbedBuilder>? embeds = null,
|
||||
NadekoInteraction? inter = null,
|
||||
IUserMessage? replyTo = null)
|
||||
=> ch.SendAsync(plainText,
|
||||
|
|
|
@ -5,20 +5,27 @@ namespace NadekoBot.Extensions;
|
|||
public sealed class MessageSenderService : IMessageSenderService, INService
|
||||
{
|
||||
private readonly IBotStrings _bs;
|
||||
private readonly IEmbedBuilderService _ebs;
|
||||
|
||||
public MessageSenderService(IBotStrings bs, IEmbedBuilderService ebs)
|
||||
public MessageSenderService(IBotStrings bs)
|
||||
{
|
||||
_bs = bs;
|
||||
_ebs = ebs;
|
||||
}
|
||||
|
||||
|
||||
public ResponseBuilder Response(IMessageChannel channel)
|
||||
=> new ResponseBuilder(_bs, _ebs)
|
||||
=> new ResponseBuilder(_bs)
|
||||
.Channel(channel);
|
||||
|
||||
public ResponseBuilder Response(ICommandContext ctx)
|
||||
=> new ResponseBuilder(_bs, _ebs)
|
||||
=> new ResponseBuilder(_bs)
|
||||
.Context(ctx);
|
||||
|
||||
public ResponseBuilder Response(IUser user)
|
||||
=> new ResponseBuilder(_bs)
|
||||
.User(user);
|
||||
|
||||
// todo fix interactions
|
||||
public ResponseBuilder Response(SocketMessageComponent smc)
|
||||
=> new ResponseBuilder(_bs)
|
||||
.Channel(smc.Channel);
|
||||
}
|
|
@ -14,13 +14,14 @@ public sealed class ResponseBuilder
|
|||
private object[] locParams = [];
|
||||
private bool shouldReply = true;
|
||||
private readonly IBotStrings _bs;
|
||||
private readonly IEmbedBuilderService _ebs;
|
||||
private EmbedBuilder? embedBuilder = null;
|
||||
private NadekoInteraction? inter;
|
||||
private Stream? fileStream = null;
|
||||
private string? fileName = null;
|
||||
|
||||
public ResponseBuilder(IBotStrings bs, IEmbedBuilderService ebs)
|
||||
public ResponseBuilder(IBotStrings bs)
|
||||
{
|
||||
_bs = bs;
|
||||
_ebs = ebs;
|
||||
}
|
||||
|
||||
private MessageReference? CreateMessageReference(IMessageChannel targetChannel)
|
||||
|
@ -43,8 +44,9 @@ public sealed class ResponseBuilder
|
|||
failIfNotExists: false);
|
||||
}
|
||||
|
||||
public async Task<IUserMessage> SendAsync()
|
||||
public async Task<IUserMessage> SendAsync(bool ephemeral = false)
|
||||
{
|
||||
// todo use ephemeral in interactions
|
||||
var targetChannel = InternalResolveChannel() ?? throw new ArgumentNullException(nameof(channel));
|
||||
var msgReference = CreateMessageReference(targetChannel);
|
||||
|
||||
|
@ -53,6 +55,15 @@ public sealed class ResponseBuilder
|
|||
if (sanitizeMentions)
|
||||
txt = txt?.SanitizeMentions(true);
|
||||
|
||||
if (this.fileStream is Stream stream)
|
||||
return await targetChannel.SendFileAsync(stream,
|
||||
filename: fileName,
|
||||
txt,
|
||||
embed: embed ?? embedBuilder?.Build(),
|
||||
components: null,
|
||||
allowedMentions: sanitizeMentions ? new(AllowedMentionTypes.Users) : AllowedMentions.All,
|
||||
messageReference: msgReference);
|
||||
|
||||
return await targetChannel.SendMessageAsync(
|
||||
txt,
|
||||
embed: embed ?? embedBuilder?.Build(),
|
||||
|
@ -65,6 +76,7 @@ public sealed class ResponseBuilder
|
|||
private ulong? InternalResolveGuildId(IMessageChannel? targetChannel)
|
||||
=> ctx?.Guild?.Id ?? (targetChannel as ITextChannel)?.GuildId;
|
||||
|
||||
// todo not good, has to go to the user
|
||||
private IMessageChannel? InternalResolveChannel()
|
||||
=> channel ?? ctx?.Channel ?? msg?.Channel;
|
||||
|
||||
|
@ -188,20 +200,14 @@ public sealed class ResponseBuilder
|
|||
private IUser? InternalResolveUser()
|
||||
=> ctx?.User ?? user ?? msg?.Author;
|
||||
|
||||
// todo embed colors
|
||||
|
||||
public ResponseBuilder Embed(EmbedBuilder eb)
|
||||
{
|
||||
embedBuilder = eb;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseBuilder Embed(Func<IEmbedBuilderService, EmbedBuilder> embedFactory)
|
||||
{
|
||||
// todo colors
|
||||
this.embed = embedFactory(_ebs).Build();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseBuilder Channel(IMessageChannel channel)
|
||||
{
|
||||
this.channel = channel;
|
||||
|
@ -238,9 +244,10 @@ public sealed class ResponseBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
public ResponseBuilder Interaction(NadekoInteraction inter)
|
||||
public ResponseBuilder Interaction(NadekoInteraction? interaction)
|
||||
{
|
||||
// todo implement
|
||||
inter = interaction;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -249,4 +256,11 @@ public sealed class ResponseBuilder
|
|||
embeds = inputEmbeds;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResponseBuilder FileName(Stream fileStream, string fileName)
|
||||
{
|
||||
this.fileStream = fileStream;
|
||||
this.fileName = fileName;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -9,11 +9,11 @@ public static class CurrencyServiceExtensions
|
|||
var wallet = await cs.GetWalletAsync(userId);
|
||||
return await wallet.GetBalance();
|
||||
}
|
||||
|
||||
|
||||
// FUTURE should be a transaction
|
||||
public static async Task<bool> TransferAsync(
|
||||
this ICurrencyService cs,
|
||||
IEmbedBuilderService ebs,
|
||||
IMessageSenderService sender,
|
||||
IUser from,
|
||||
IUser to,
|
||||
long amount,
|
||||
|
@ -29,17 +29,20 @@ public static class CurrencyServiceExtensions
|
|||
{
|
||||
try
|
||||
{
|
||||
await to.SendConfirmAsync(ebs,
|
||||
string.IsNullOrWhiteSpace(note)
|
||||
? $"Received {formattedAmount} from {from} "
|
||||
: $"Received {formattedAmount} from {from}: {note}");
|
||||
await sender.Response(to)
|
||||
.Confirm(string.IsNullOrWhiteSpace(note)
|
||||
? $"Received {formattedAmount} from {from} "
|
||||
: $"Received {formattedAmount} from {from}: {note}")
|
||||
.SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//ignored
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +1,17 @@
|
|||
#nullable disable
|
||||
using NadekoBot.Common.Configs;
|
||||
|
||||
// todo remove
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface IEmbedBuilderService
|
||||
// todo remove
|
||||
public sealed class DiscordEmbedBuilderWrapper
|
||||
{
|
||||
EmbedBuilder Create(ICommandContext ctx = null);
|
||||
}
|
||||
// public EmbedBuilder WithColor(EmbedColor color)
|
||||
// => color switch
|
||||
// {
|
||||
// EmbedColor.Ok => Wrap(embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())),
|
||||
// EmbedColor.Pending => Wrap(embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())),
|
||||
// EmbedColor.Error => Wrap(embed.WithColor(_botConfig.Color.Error.ToDiscordColor())),
|
||||
// _ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type")
|
||||
// };
|
||||
|
||||
public class EmbedBuilderService : IEmbedBuilderService, INService
|
||||
{
|
||||
private readonly BotConfigService _botConfigService;
|
||||
|
||||
public EmbedBuilderService(BotConfigService botConfigService)
|
||||
=> _botConfigService = botConfigService;
|
||||
|
||||
public EmbedBuilder Create(ICommandContext ctx = null)
|
||||
=> new EmbedBuilder();
|
||||
|
||||
}
|
||||
|
||||
public sealed class DiscordEmbedBuilderWrapper : IEmbedBuilder
|
||||
{
|
||||
private readonly BotConfig _botConfig;
|
||||
private EmbedBuilder embed;
|
||||
|
||||
public DiscordEmbedBuilderWrapper(in BotConfig botConfig, EmbedBuilder embed = null)
|
||||
{
|
||||
_botConfig = botConfig;
|
||||
this.embed = embed ?? new EmbedBuilder();
|
||||
}
|
||||
|
||||
public EmbedBuilder WithDescription(string desc)
|
||||
=> Wrap(embed.WithDescription(desc));
|
||||
|
||||
public EmbedBuilder WithTitle(string title)
|
||||
=> Wrap(embed.WithTitle(title));
|
||||
|
||||
public EmbedBuilder AddField(string title, object value, bool isInline = false)
|
||||
=> Wrap(embed.AddField(title, value, isInline));
|
||||
|
||||
public EmbedBuilder WithFooter(string text, string iconUrl = null)
|
||||
=> Wrap(embed.WithFooter(text, iconUrl));
|
||||
|
||||
public EmbedBuilder WithAuthor(string name, string iconUrl = null, string url = null)
|
||||
=> Wrap(embed.WithAuthor(name, iconUrl, url));
|
||||
|
||||
public EmbedBuilder WithUrl(string url)
|
||||
=> Wrap(embed.WithUrl(url));
|
||||
|
||||
public EmbedBuilder WithImageUrl(string url)
|
||||
=> Wrap(embed.WithImageUrl(url));
|
||||
|
||||
public EmbedBuilder WithThumbnailUrl(string url)
|
||||
=> Wrap(embed.WithThumbnailUrl(url));
|
||||
|
||||
public EmbedBuilder WithColor(EmbedColor color)
|
||||
=> color switch
|
||||
{
|
||||
EmbedColor.Ok => Wrap(embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())),
|
||||
EmbedColor.Pending => Wrap(embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())),
|
||||
EmbedColor.Error => Wrap(embed.WithColor(_botConfig.Color.Error.ToDiscordColor())),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type")
|
||||
};
|
||||
|
||||
public EmbedBuilder WithDiscordColor(Color color)
|
||||
=> Wrap(embed.WithColor(color));
|
||||
|
||||
public Embed Build()
|
||||
=> embed.Build();
|
||||
|
||||
private EmbedBuilder Wrap(EmbedBuilder eb)
|
||||
{
|
||||
embed = eb;
|
||||
return eb;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ public sealed class CommandsUtilityService : ICommandsUtilityService, INService
|
|||
private readonly CommandHandler _ch;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordPermOverrideService _dpos;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly ILocalization _loc;
|
||||
private readonly IMedusaLoaderService _medusae;
|
||||
|
||||
|
@ -16,14 +16,14 @@ public sealed class CommandsUtilityService : ICommandsUtilityService, INService
|
|||
CommandHandler ch,
|
||||
IBotStrings strings,
|
||||
DiscordPermOverrideService dpos,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
ILocalization loc,
|
||||
IMedusaLoaderService medusae)
|
||||
{
|
||||
_ch = ch;
|
||||
_strings = strings;
|
||||
_dpos = dpos;
|
||||
_eb = eb;
|
||||
_sender = sender;
|
||||
_loc = loc;
|
||||
_medusae = medusae;
|
||||
}
|
||||
|
|
|
@ -60,31 +60,34 @@ public static class SocketMessageComponentExtensions
|
|||
|
||||
public static Task RespondAsync(
|
||||
this SocketMessageComponent ch,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
string text,
|
||||
MsgType type,
|
||||
bool ephemeral = false,
|
||||
NadekoInteraction? inter = null)
|
||||
{
|
||||
var builder = new EmbedBuilder().WithDescription(text);
|
||||
var embed = new EmbedBuilder().WithDescription(text);
|
||||
|
||||
builder = (type switch
|
||||
embed = (type switch
|
||||
{
|
||||
MsgType.Error => builder.WithErrorColor(),
|
||||
MsgType.Ok => builder.WithOkColor(),
|
||||
MsgType.Pending => builder.WithPendingColor(),
|
||||
MsgType.Error => embed.WithErrorColor(),
|
||||
MsgType.Ok => embed.WithOkColor(),
|
||||
MsgType.Pending => embed.WithPendingColor(),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
});
|
||||
|
||||
return ch.EmbedAsync(builder, inter: inter, ephemeral: ephemeral);
|
||||
return sender.Response(ch)
|
||||
.Embed(embed)
|
||||
.Interaction(inter)
|
||||
.SendAsync(ephemeral: ephemeral);
|
||||
}
|
||||
|
||||
// embed title and optional footer overloads
|
||||
|
||||
public static Task RespondConfirmAsync(
|
||||
this SocketMessageComponent smc,
|
||||
IEmbedBuilderService eb,
|
||||
IMessageSenderService sender,
|
||||
string text,
|
||||
bool ephemeral = false)
|
||||
=> smc.RespondAsync(eb, text, MsgType.Ok, ephemeral);
|
||||
=> smc.RespondAsync(sender, text, MsgType.Ok, ephemeral);
|
||||
}
|
|
@ -4,21 +4,6 @@ namespace NadekoBot.Extensions;
|
|||
|
||||
public static class UserExtensions
|
||||
{
|
||||
public static async Task<IUserMessage> EmbedAsync(this IUser user, EmbedBuilder embed, string msg = "")
|
||||
{
|
||||
var ch = await user.CreateDMChannelAsync();
|
||||
return await ch.EmbedAsync(embed, msg);
|
||||
}
|
||||
|
||||
public static async Task<IUserMessage> SendAsync(this IUser user, SmartText text, bool sanitizeAll = false)
|
||||
{
|
||||
var ch = await user.CreateDMChannelAsync();
|
||||
return await ch.SendAsync(text, sanitizeAll);
|
||||
}
|
||||
|
||||
public static async Task<IUserMessage> SendConfirmAsync(this IUser user, IEmbedBuilderService eb, string text)
|
||||
=> await user.SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text).Build());
|
||||
|
||||
// This method is used by everything that fetches the avatar from a user
|
||||
public static Uri RealAvatarUrl(this IUser usr, ushort size = 256)
|
||||
=> usr.AvatarId is null ? new(usr.GetDefaultAvatarUrl()) : new Uri(usr.GetAvatarUrl(ImageFormat.Auto, size));
|
||||
|
|
Loading…
Reference in a new issue