Skip to content

Commit

Permalink
QuoteMessage now supports a reply being specified. get-threshold is n…
Browse files Browse the repository at this point in the history
…ow more readable.
  • Loading branch information
SquirrelKiev committed May 6, 2024
1 parent 5e817fb commit 29f51d0
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 40 deletions.
50 changes: 46 additions & 4 deletions Asahi/Modules/Common/QuotingHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,32 @@ public static class QuotingHelpers
// Not the nuclear kind (I guess some of them could be considered pretty nuclear?)
public const string ReactionsFieldName = "Reactors";

/// <remarks>If <see cref="spoilerAll"/> is true, return value will always be a length of 1.</remarks>
public static List<MessageContents> QuoteMessage(IMessage message, Color embedColor, ILogger logger,
bool webhookMode, bool spoilerAll = false, string? spoilerContext = "")
bool showAuthor, bool spoilerAll = false, string? spoilerContext = "", IMessage? replyMessage = null, Action<EmbedBuilder>? modifyQuoteEmbed = null)
{
var constantUrl = CatboxQts.GetRandomQtUrl();

//var channelName = message.Channel is SocketThreadChannel threadChannel ? $"#{threadChannel.ParentChannel.Name} • " : "";

var channelName = $"#{message.Channel.Name}";

List<MessageContents>? replyMessages = null;
if (replyMessage != null)
{
showAuthor = true;
replyMessages = QuoteMessage(replyMessage, embedColor, logger, showAuthor, spoilerAll, modifyQuoteEmbed:
eb =>
{
eb.WithFooter(new EmbedFooterBuilder());
eb.Timestamp = null;
});
}

if (message.Channel is SocketThreadChannel threadChannel)
{
channelName += $" • #{threadChannel.ParentChannel.Name}";
}

var messageContent = message.Content;

if (spoilerAll)
Expand All @@ -41,7 +52,7 @@ public static List<MessageContents> QuoteMessage(IMessage message, Color embedCo
.WithOptionalColor(embedColor)
.WithUrl(constantUrl);

if (!webhookMode)
if (showAuthor)
{
firstEmbed.WithAuthor(message.Author);
}
Expand Down Expand Up @@ -179,8 +190,39 @@ public static List<MessageContents> QuoteMessage(IMessage message, Color embedCo
firstEmbed.WithDescription("*No content.*");
}

modifyQuoteEmbed?.Invoke(firstEmbed);

queuedMessages.Insert(0, new MessageContents(link, embeds.Take(10).Select(x => x.Build()).ToArray(), null));

if (replyMessages != null)
{
var firstReplyMessage = replyMessages[0];
var replyMessageAuthor = firstReplyMessage.embeds![0].Author!.Value;
firstReplyMessage.embeds![0] = firstReplyMessage.embeds![0].ToEmbedBuilder()
.WithAuthor($"Replying to {replyMessageAuthor.Name}", replyMessageAuthor.IconUrl, replyMessageAuthor.Url).Build();

if (replyMessages.Count == 1 && queuedMessages[0].embeds?.Length < 10)
{
replyMessages[0] = firstReplyMessage;

var firstMessage = queuedMessages[0];
firstMessage.embeds = [.. replyMessages[0].embeds!, .. queuedMessages[0].embeds!];
queuedMessages[0] = firstMessage;
}
else
{
var firstQueuedMessage = queuedMessages[0];

firstReplyMessage.body = firstQueuedMessage.body;
firstQueuedMessage.body = "";

replyMessages[0] = firstReplyMessage;
queuedMessages[0] = firstQueuedMessage;

queuedMessages.InsertRange(0, replyMessages);
}
}

return queuedMessages;
}

Expand Down
29 changes: 17 additions & 12 deletions Asahi/Modules/Highlights/HighlightsModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public Task CreateSlash(
[Summary(description: "The channel to log highlights to. Can be changed later.")]
ITextChannel channel)
{
return CommonConfig(name, async (context, cleanName) =>
return CommonConfig(name, async (context, cleanName, _) =>
{
if (await context.HighlightBoards.AnyAsync(x => x.GuildId == Context.Guild.Id && x.Name == cleanName))
{
Expand Down Expand Up @@ -56,7 +56,7 @@ public Task RemoveSlash(
[Autocomplete(typeof(HighlightsNameAutocomplete))]
string name)
{
return CommonConfig(name, async (context, cleanName) =>
return CommonConfig(name, async (context, cleanName, _) =>
{
var board = await context.HighlightBoards.FirstOrDefaultAsync(x => x.Name == name);
if (board == null)
Expand Down Expand Up @@ -957,7 +957,7 @@ public Task AddEmoteAliasSlash(
[Summary(description: "The emote to replace with.")] [MaxLength(100)]
IEmote emote)
{
return CommonConfig(null, async (context, _) =>
return CommonConfig(null, async (context, _, _) =>
{
emoteName = emoteName.ToLowerInvariant();

Expand Down Expand Up @@ -985,7 +985,7 @@ public Task RemoveEmoteAliasSlash(
[Autocomplete(typeof(AliasedEmoteAutocomplete))]
string emoteName)
{
return CommonConfig(null, async (context, _) =>
return CommonConfig(null, async (context, _, _) =>
{
emoteName = emoteName.ToLowerInvariant();

Expand Down Expand Up @@ -1186,7 +1186,7 @@ public Task GetCurrentChannelsThresholdSlash(

HighlightsTrackingService.CalculateThreshold(threshold, hts.GetCachedMessages(channel.Id), DateTimeOffset.UtcNow, out var message);

return Task.FromResult(new ConfigChangeResult(true, message));
return Task.FromResult(new ConfigChangeResult(true, $"Threshold info for <#{channel.Id}>\n\n{message}"));
}, boards => boards.Include(x => x.Thresholds));
}

Expand Down Expand Up @@ -1263,18 +1263,19 @@ public ConfigChangeResult(bool wasSuccess, string message) : this(wasSuccess, me
}
}

public struct ConfigChangeOptions(BotDbContext context, HighlightBoard board, string name)
public struct ConfigChangeOptions(BotDbContext context, HighlightBoard board, string name, EmbedBuilder embedBuilder)
{
public BotDbContext context = context;
public HighlightBoard board = board;
public string name = name;
public EmbedBuilder embedBuilder = embedBuilder;
}

public static partial class HighlightsModuleUtility
{
public static async Task<bool> CommonConfig(IInteractionContext botContext, DbService dbService,
string? name,
Func<BotDbContext, string, Task<ConfigChangeResult>> updateAction)
Func<BotDbContext, string, EmbedBuilder, Task<ConfigChangeResult>> updateAction)
{
await botContext.Interaction.DeferAsync();
if (name != null)
Expand All @@ -1290,13 +1291,14 @@ public static async Task<bool> CommonConfig(IInteractionContext botContext, DbSe

await using var context = dbService.GetDbContext();

var message = await updateAction(context, name ?? "(N/A)");
var embedBuilder = new EmbedBuilder();
var message = await updateAction(context, name ?? "(N/A)", embedBuilder);

if (message.wasSuccess)
await context.SaveChangesAsync();

await botContext.Interaction.FollowupAsync(embeds: message.extraEmbeds.Prepend(
new EmbedBuilder()
embedBuilder
.WithAuthor(name)
.WithDescription(message.message)
.WithColor(message.wasSuccess ? Color.Green : Color.Red)
Expand All @@ -1312,7 +1314,7 @@ public static Task<bool> CommonBoardConfig(IInteractionContext botContext, DbSer
{
highlightBoardModifier ??= boards => boards;

return CommonConfig(botContext, dbService, userSetName, async (context, name) =>
return CommonConfig(botContext, dbService, userSetName, async (context, name, eb) =>
{
var board = await highlightBoardModifier(context.HighlightBoards).FirstOrDefaultAsync(x => x.GuildId == botContext.Guild.Id && x.Name == name);

Expand All @@ -1321,7 +1323,7 @@ public static Task<bool> CommonBoardConfig(IInteractionContext botContext, DbSer
return new ConfigChangeResult(false, $"`{name}` does not exist.");
}

return await updateAction(new ConfigChangeOptions(context, board, name));
return await updateAction(new ConfigChangeOptions(context, board, name, eb));
});
}

Expand All @@ -1344,6 +1346,9 @@ public static Task<bool> CommonThresholdConfig(IInteractionContext botContext, D
return new ConfigChangeResult(false, $"<#{overrideId}> does not have an override. Create one first.");
}

var overrideName = (await botContext.Guild.GetChannelAsync(threshold.OverrideId))?.Name;
overrideName = overrideName == null ? (await botContext.Client.GetGuildAsync(threshold.OverrideId)).Name : $"#{overrideName}";
options.embedBuilder.WithFooter(overrideName);
return await updateAction(options, threshold);
}, x => x.Include(y => y.Thresholds));
}
Expand All @@ -1357,7 +1362,7 @@ public class HighlightsSubmodule(DbService dbService) : BotModule
protected readonly DbService dbService = dbService;

protected Task<bool> CommonConfig(string? name,
Func<BotDbContext, string, Task<ConfigChangeResult>> updateAction)
Func<BotDbContext, string, EmbedBuilder, Task<ConfigChangeResult>> updateAction)
{
return HighlightsModuleUtility.CommonConfig(Context, dbService, name, updateAction);
}
Expand Down
63 changes: 51 additions & 12 deletions Asahi/Modules/Highlights/HighlightsTrackingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,16 +439,25 @@ private async Task SendAndTrackHighlightMessage(HighlightBoard board, EmoteAlias

var spoilerEntry = board.SpoilerChannels.FirstOrDefault(x => x.ChannelId == message.Channel.Id);

var queuedMessages =
QuotingHelpers.QuoteMessage(message, embedColor, logger, true, spoilerEntry != null, spoilerEntry?.SpoilerContext ?? "");

var eb = queuedMessages[0].embeds?[0].ToEmbedBuilder();
if (eb != null)
IMessage? replyMessage = null;
if (message.Reference != null)
{
AddReactionsFieldToQuote(eb, reactions, totalUniqueReactions);
queuedMessages[0].embeds![0] = eb.Build();
if (message.Reference.ChannelId == message.Channel.Id)
{
if (message.Reference.MessageId.IsSpecified)
{
replyMessage = await message.Channel.GetMessageAsync(message.Reference.MessageId.Value);
}
}
}

var queuedMessages =
QuotingHelpers.QuoteMessage(message, embedColor, logger, false, spoilerEntry != null,
spoilerEntry?.SpoilerContext ?? "", replyMessage, eb =>
{
AddReactionsFieldToQuote(eb, reactions, totalUniqueReactions);
});

var webhook = await loggingChannel.GetOrCreateWebhookAsync(BotService.WebhookDefaultName);
var webhookClient = new DiscordWebhookClient(webhook);
List<ulong> highlightMessages = [];
Expand Down Expand Up @@ -555,10 +564,34 @@ public async Task AutoReact(HighlightBoard board, EmoteAlias[] aliases, IReadOnl
}
}

public struct ThresholdInfo
{
public required double CurrentThreshold { get; set; }
public required double RawThreshold { get; set; }
public required double WeightedUserCount { get; set; }
public required int UnweightedUserCount { get; set; }
public required bool IsHighActivity { get; set; }
public required int TotalCachedMessages { get; set; }
public required int CachedMessagesBeingConsidered { get; set; }

public readonly override string ToString()
{
return $"**Important info:**\n" +
$"Current threshold: `{CurrentThreshold}`\n" +
$"Weighted users: `{WeightedUserCount}`\n" +
$"Activity level: {(IsHighActivity ? "`High`" : "`Normal`")}\n\n" +
$"**Extra debug info:**\n" +
$"Raw threshold: `{RawThreshold}`\n" +
$"Unweighted users: `{UnweightedUserCount}`\n" +
$"Total messages cached: `{TotalCachedMessages}`\n" +
$"Cached messages being considered in user count: `{CachedMessagesBeingConsidered}`";
}
}

public static int CalculateThreshold(HighlightThreshold thresholdConfig,
IReadOnlyCollection<HighlightsTrackingService.CachedMessage> messages,
DateTimeOffset messageSentAt,
out string debugInfo)
out ThresholdInfo debugInfo)
{
Dictionary<ulong, double> userWeights = [];

Expand Down Expand Up @@ -602,10 +635,16 @@ public static int CalculateThreshold(HighlightThreshold thresholdConfig,
var roundedThreshold = Math.Min(thresholdConfig.MaxThreshold,
thresholdDecimal < thresholdConfig.RoundingThreshold ? Math.Floor(rawThreshold) : Math.Ceiling(rawThreshold));

debugInfo = $"Current threshold is {roundedThreshold}. Raw threshold is `{rawThreshold}`. " +
$"weighted users is `{weightedUserCount}`, unweighted users is `{userWeights.Count}`. " +
$"{(highActivity ? "`Channel is high activity!` " : "`Normal activity levels.` ")}" +
$"Total of `{orderedMessages.Length}` messages cached, `{userWeightMessages.Length}` of which are being considered for unique user count.";
debugInfo = new ThresholdInfo()
{
CurrentThreshold = roundedThreshold,
RawThreshold = rawThreshold,
WeightedUserCount = weightedUserCount,
UnweightedUserCount = userWeights.Count,
IsHighActivity = highActivity,
TotalCachedMessages = orderedMessages.Length,
CachedMessagesBeingConsidered = userWeightMessages.Length
};

return (int)roundedThreshold;
}
Expand Down
35 changes: 23 additions & 12 deletions Asahi/Modules/ModSpoilers/ModSpoilerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,29 @@ await webhookClient.SendFilesAsync(attachmentStreams, contents, username: userna
cachedHighlightedMessage.HighlightBoard.FallbackEmbedColor,
ogMessage.Author as IGuildUser,
client);
var messageContents = QuotingHelpers.QuoteMessage(ogMessage, quoteEmbedColor, logger, true, true, context);

IMessage? replyMessage = null;
if (ogMessage.Reference != null)
{
if (ogMessage.Reference.ChannelId == ogMessage.Channel.Id)
{
if (ogMessage.Reference.MessageId.IsSpecified)
{
replyMessage = await ogMessage.Channel.GetMessageAsync(ogMessage.Reference.MessageId.Value);
}
}
}

var firstMessageObj = await loggingChannel.GetMessageAsync(cachedHighlightedMessage.HighlightMessageIds[0]);
var (uniqueReactionUsersAutoReact, uniqueReactionEmotes) =
await hts.GetReactions(channel.Guild, [ogMessage, firstMessageObj], [ogMessage]);

var messageContents = QuotingHelpers.QuoteMessage(ogMessage, quoteEmbedColor, logger, false, true, context,
replyMessage, eb =>
{
hts.AddReactionsFieldToQuote(eb,
uniqueReactionEmotes.Select(x => new ReactionInfo(x)), uniqueReactionUsersAutoReact.Count);
});

var i = 0;
bool deletedMessage = false;
Expand All @@ -123,22 +145,11 @@ await webhookClient.SendFilesAsync(attachmentStreams, contents, username: userna
{
var firstMessage = messageContents[0];

var firstMessageObj = await loggingChannel.GetMessageAsync(cachedHighlightedMessage.HighlightMessageIds[0]);
var (uniqueReactionUsersAutoReact, uniqueReactionEmotes) =
await hts.GetReactions(channel.Guild, [ogMessage, firstMessageObj], [ogMessage]);

if (firstMessage.embeds == null)
{
return new SpoilerAttemptResult(false, "New highlight message missing embeds.");
}

var eb = firstMessage.embeds[0].ToEmbedBuilder();

hts.AddReactionsFieldToQuote(eb,
uniqueReactionEmotes.Select(x => new ReactionInfo(x)), uniqueReactionUsersAutoReact.Count);

firstMessage.embeds[0] = eb.Build();

await webhookClient.ModifyMessageAsync(highlightMessageId, props =>
{
props.Content = firstMessage.body;
Expand Down

0 comments on commit 29f51d0

Please sign in to comment.