ProjectMakoto/ProjectMakoto/Events/EmbedMessagesEvents.cs

175 lines
8.3 KiB
C#

// Project Makoto
// Copyright (C) 2024 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
namespace ProjectMakoto.Events;
internal sealed class EmbedMessagesEvents(Bot bot) : RequiresTranslation(bot)
{
Translations.events.embedMessages tKey => this.t.Events.EmbedMessages;
internal async Task MessageCreated(DiscordClient sender, MessageCreateEventArgs e)
{
if (e.Guild is null)
return;
var Delete = new DiscordButtonComponent(ButtonStyle.Danger, "DeleteEmbedMessage", this.tKey.Delete.Get(this.Bot.Guilds[e.Guild.Id]), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("🗑")));
do
{
if (RegexTemplates.DiscordChannelUrl.IsMatch(e.Message.Content))
{
if (!this.Bot.Guilds[e.Guild.Id].EmbedMessage.UseEmbedding)
break;
if (await this.Bot.Users[e.Message.Author.Id].Cooldown.WaitForModerate(new SharedCommandContext(e.Message, this.Bot, "message_embed"), true))
break;
var matches = RegexTemplates.DiscordChannelUrl.Matches(e.Message.Content);
foreach (var b in matches.GroupBy(x => x.Value).Select(y => y.FirstOrDefault()).Take(2))
{
if (!b.Value.TryParseMessageLink(out var GuildId, out var ChannelId, out var MessageId))
continue;
if (GuildId != e.Guild.Id)
continue;
if (!e.Guild.Channels.ContainsKey(ChannelId))
continue;
var channel = e.Guild.GetChannel(ChannelId);
var perms = channel.PermissionsFor(await e.Author.ConvertToMember(e.Guild));
if (!perms.HasPermission(Permissions.AccessChannels) || !perms.HasPermission(Permissions.ReadMessageHistory))
continue;
if (!channel.TryGetMessage(MessageId, out var message))
continue;
var JumpToMessage = new DiscordLinkButtonComponent(message.JumpLink.ToString(), this.t.Common.JumpToMessage.Get(this.Bot.Guilds[e.Guild.Id]), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("💬")));
var msg = await e.Message.RespondAsync(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder
{
Author = new DiscordEmbedBuilder.EmbedAuthor { IconUrl = message.Author.AvatarUrl, Name = $"{message.Author.GetUsernameWithIdentifier()}" },
Color = message.Author.BannerColor ?? EmbedColors.Info,
Description = $"{message.ConvertToText()}".TruncateWithIndication(2000),
ImageUrl = (message.Attachments?.Count > 0 && (message.Attachments[0].Filename.EndsWith(".png")
|| message.Attachments[0].Filename.EndsWith(".jpeg")
|| message.Attachments[0].Filename.EndsWith(".jpg")
|| message.Attachments[0].Filename.EndsWith(".gif")) ? message.Attachments[0].Url.ToString() : ""),
Timestamp = message.Timestamp,
}).AddComponents(JumpToMessage, Delete));
}
}
} while (false);
if (RegexTemplates.GitHubUrl.IsMatch(e.Message.Content))
{
if (!this.Bot.Guilds[e.Guild.Id].EmbedMessage.UseGithubEmbedding)
return;
SharedCommandContext ctx = new(e.Message, this.Bot, "github_embed");
if (await this.Bot.Users[e.Message.Author.Id].Cooldown.WaitForModerate(ctx, true))
return;
ctx.BaseCommand.DeleteOrInvalidate();
var matches = RegexTemplates.GitHubUrl.Matches(e.Message.Content);
foreach (var b in matches.GroupBy(x => x.Value).Select(y => y.FirstOrDefault()).Take(2))
{
var fileUrl = b.Value;
fileUrl = fileUrl.Replace("github.com", "raw.githubusercontent.com");
fileUrl = fileUrl.Replace("/blob", "");
fileUrl = fileUrl[..fileUrl.LastIndexOf('#')];
var repoOwner = b.Groups[1].Value;
var repoName = b.Groups[2].Value;
var relativeFilePath = b.Groups[5].Value;
var fileEnding = "";
try
{
fileEnding = relativeFilePath.Remove(0, relativeFilePath.LastIndexOf('.') + 1);
}
catch { }
var StartLine = Convert.ToUInt32(b.Groups[6].Value.Replace("L", ""));
var EndLine = Convert.ToUInt32(b.Groups[8].Value.IsNullOrWhiteSpace() ? $"{StartLine}" : b.Groups[8].Value.Replace("L", ""));
if (EndLine < StartLine)
return;
var rawFile = await new HttpClient().GetStringAsync(fileUrl);
rawFile = rawFile.ReplaceLineEndings("\n");
var lines = rawFile.Split("\n").Skip((int)(StartLine - 1)).Take((int)(EndLine - (StartLine - 1))).Select(x => x.Replace("\t", " ")).ToList();
if (!lines.IsNotNullAndNotEmpty())
return;
var shortestIndent = -1;
foreach (var c in lines)
{
var currentIndent = 0;
foreach (var d in c)
{
if (d is ' ' or '\t')
currentIndent++;
else
break;
}
if (currentIndent < shortestIndent || shortestIndent == -1)
shortestIndent = currentIndent;
}
lines = lines.Select(x => x.Remove(0, shortestIndent)).ToList();
var content = $"`{relativeFilePath}` {(StartLine != EndLine ? this.tKey.Lines.Get(this.Bot.Guilds[e.Guild.Id]).Build(new TVar("Start", StartLine), new TVar("End", EndLine)) : this.tKey.Line.Get(this.Bot.Guilds[e.Guild.Id]).Build(new TVar("Start", StartLine)))}\n\n" +
$"```{fileEnding}\n" +
$"{string.Join("\n", lines)}\n" +
$"```";
content = content.TruncateWithIndication(1997);
if (!content.EndsWith("```"))
content += "```";
var msg = await e.Message.RespondAsync(new DiscordMessageBuilder().WithContent(content).AddComponents(Delete));
_ = e.Message.ModifySuppressionAsync(true);
}
}
}
internal async Task ComponentInteractionCreated(DiscordClient sender, ComponentInteractionCreateEventArgs e)
{
if (e.GetCustomId() == "DeleteEmbedMessage")
{
var fullMsg = await e.Message.Refetch();
_ = e.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate);
_ = (fullMsg.Reference is not null && fullMsg.ReferencedMessage is null) ||
(fullMsg.ReferencedMessage is not null && fullMsg.ReferencedMessage.Author.Id == e.Interaction.User.Id) ||
(await e.User.ConvertToMember(e.Interaction.Guild)).Roles.Any(x => (x.CheckPermission(Permissions.ManageMessages) == PermissionLevel.Allowed) || (x.CheckPermission(Permissions.Administrator) == PermissionLevel.Allowed))
? fullMsg.DeleteAsync().ContinueWith(x =>
{
if (!x.IsCompletedSuccessfully)
_ = e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent($"❌ `{this.tKey.FailedToDelete.Get(this.Bot.Guilds[e.Guild.Id])}`").AsEphemeral());
})
: e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent($"❌ `{this.tKey.NotAuthor.Get(this.Bot.Guilds[e.Guild.Id])}`").AsEphemeral());
}
}
}