Refactor some mention rendering code to not be Discord -> Minecraft specific

This commit is contained in:
Vankka 2023-11-22 01:15:06 +02:00
parent 24e0529b69
commit 1d5a5381a0
No known key found for this signature in database
GPG Key ID: 6E50CB7A29B96AD0
3 changed files with 147 additions and 93 deletions

View File

@ -28,6 +28,7 @@ import com.discordsrv.api.event.events.message.process.discord.DiscordChatMessag
import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.component.util.ComponentUtil;
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
import com.discordsrv.common.config.main.generic.MentionsConfig;
import dev.vankka.mcdiscordreserializer.renderer.implementation.DefaultMinecraftRenderer;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
@ -35,6 +36,7 @@ import net.dv8tion.jda.api.utils.MiscUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
import java.util.regex.Matcher;
@ -75,18 +77,32 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
@Override
public Component appendLink(@NotNull Component part, String link) {
JDA jda = discordSRV.jda();
Component messageLink = makeMessageLink(link);
if (messageLink == null) {
return super.appendLink(part, link);
}
return part.append(messageLink);
}
public Component makeMessageLink(String link) {
JDA jda = discordSRV.jda();
if (jda == null) {
return null;
}
if (jda != null) {
Matcher matcher = MESSAGE_URL_PATTERN.matcher(link);
if (matcher.matches()) {
if (!matcher.matches()) {
return null;
}
String channel = matcher.group(1);
GuildChannel guildChannel = jda.getGuildChannelById(channel);
Context context = CONTEXT.get();
String format = context != null ? context.config.mentions.messageUrl : null;
if (format == null || guildChannel == null) {
return super.appendLink(part, link);
return null;
}
return Component.text()
@ -103,47 +119,58 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
)
.build();
}
}
return super.appendLink(part, link);
}
@Override
public @NotNull Component appendChannelMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get();
DiscordToMinecraftChatConfig.Mentions.Format format = context != null ? context.config.mentions.channel : null;
MentionsConfig.Format format = context != null ? context.config.mentions.channel : null;
if (format == null) {
return component.append(Component.text("<#" + id + ">"));
}
Component mention = makeChannelMention(MiscUtil.parseLong(id), format);
if (mention == null) {
return component;
}
return component.append(mention);
}
@Nullable
public Component makeChannelMention(long id, MentionsConfig.Format format) {
JDA jda = discordSRV.jda();
if (jda == null) {
return Component.empty();
return null;
}
GuildChannel guildChannel = jda.getGuildChannelById(id);
return component.append(ComponentUtil.fromAPI(
return ComponentUtil.fromAPI(
discordSRV.componentFactory()
.textBuilder(guildChannel != null ? format.format : format.unknownFormat)
.addContext(guildChannel)
.applyPlaceholderService()
.build()
));
);
}
@Override
public @NotNull Component appendUserMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get();
DiscordToMinecraftChatConfig.Mentions.Format format = context != null ? context.config.mentions.user : null;
MentionsConfig.Format format = context != null ? context.config.mentions.user : null;
DiscordGuild guild = context != null ? context.guild : null;
if (format == null || guild == null) {
return component.append(Component.text("<@" + id + ">"));
}
long userId = MiscUtil.parseLong(id);
DiscordUser user = discordSRV.discordAPI().getUserById(userId);
DiscordGuildMember member = guild.getMemberById(userId);
return component.append(makeUserMention(userId, format, guild));
}
@NotNull
public Component makeUserMention(long id, MentionsConfig.Format format, DiscordGuild guild) {
DiscordUser user = discordSRV.discordAPI().getUserById(id);
DiscordGuildMember member = guild.getMemberById(id);
GameTextBuilder builder = discordSRV.componentFactory()
.textBuilder(user != null ? format.format : format.unknownFormat);
@ -155,21 +182,25 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
builder.addContext(member);
}
return component.append(ComponentUtil.fromAPI(
return ComponentUtil.fromAPI(
builder.applyPlaceholderService().build()
));
);
}
@Override
public @NotNull Component appendRoleMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get();
DiscordToMinecraftChatConfig.Mentions.Format format = context != null ? context.config.mentions.role : null;
MentionsConfig.Format format = context != null ? context.config.mentions.role : null;
if (format == null) {
return component.append(Component.text("<#" + id + ">"));
}
long roleId = MiscUtil.parseLong(id);
DiscordRole role = discordSRV.discordAPI().getRoleById(roleId);
return component.append(makeRoleMention(roleId, format));
}
public Component makeRoleMention(long id, MentionsConfig.Format format) {
DiscordRole role = discordSRV.discordAPI().getRoleById(id);
GameTextBuilder builder = discordSRV.componentFactory()
.textBuilder(role != null ? format.format : format.unknownFormat);
@ -178,9 +209,9 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
builder.addContext(role);
}
return component.append(ComponentUtil.fromAPI(
return ComponentUtil.fromAPI(
builder.applyPlaceholderService().build()
));
);
}
@Override
@ -190,31 +221,39 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
@NotNull String id
) {
Context context = CONTEXT.get();
DiscordToMinecraftChatConfig.EmoteBehaviour behaviour = context != null ? context.config.customEmojiBehaviour : null;
if (behaviour == null || behaviour == DiscordToMinecraftChatConfig.EmoteBehaviour.HIDE) {
MentionsConfig.EmoteBehaviour behaviour = context != null ? context.config.mentions.customEmojiBehaviour : null;
if (behaviour == null || behaviour == MentionsConfig.EmoteBehaviour.HIDE) {
return component;
}
long emojiId = MiscUtil.parseLong(id);
DiscordCustomEmoji emoji = discordSRV.discordAPI().getEmojiById(emojiId);
if (emoji == null) {
Component emoteMention = makeEmoteMention(emojiId, behaviour);
if (emoteMention == null) {
return component;
}
return component.append(emoteMention);
}
public Component makeEmoteMention(long id, MentionsConfig.EmoteBehaviour behaviour) {
DiscordCustomEmoji emoji = discordSRV.discordAPI().getEmojiById(id);
if (emoji == null) {
return null;
}
DiscordChatMessageCustomEmojiRenderEvent event = new DiscordChatMessageCustomEmojiRenderEvent(emoji);
discordSRV.eventBus().publish(event);
if (event.isProcessed()) {
Component rendered = ComponentUtil.fromAPI(event.getRenderedEmojiFromProcessing());
return component.append(rendered);
return ComponentUtil.fromAPI(event.getRenderedEmojiFromProcessing());
}
switch (behaviour) {
case NAME:
return component.append(Component.text(":" + emoji.getName() + ":"));
return Component.text(":" + emoji.getName() + ":");
case BLANK:
default:
return component;
return null;
}
}

View File

@ -20,6 +20,7 @@ package com.discordsrv.common.config.main.channels;
import com.discordsrv.common.config.configurate.annotation.Untranslated;
import com.discordsrv.common.config.main.generic.DiscordIgnoresConfig;
import com.discordsrv.common.config.main.generic.MentionsConfig;
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
import org.spongepowered.configurate.objectmapping.meta.Comment;
@ -55,37 +56,7 @@ public class DiscordToMinecraftChatConfig {
public DiscordIgnoresConfig ignores = new DiscordIgnoresConfig();
@Comment("The representations of Discord mentions in-game")
public Mentions mentions = new Mentions();
@ConfigSerializable
public static class Mentions {
public Format role = new Format("%role_color%@%role_name%", "[color:#5865F2]@deleted-role");
public Format channel = new Format("[hover:show_text:Click to go to channel][click:open_url:%channel_jump_url%][color:#5865F2]#%channel_name%", "[color:#5865F2]#Unknown");
public Format user = new Format("[hover:show_text:Username: @%user_tag%\nRoles: %user_roles:', '|text:'[color:gray][italics:on]None[color][italics]'%][color:#5865F2]@%user_effective_server_name|user_effective_name%", "[color:#5865F2]@Unknown user");
public String messageUrl = "[hover:show_text:Click to go to message][click:open_url:%jump_url%][color:#5865F2]#%channel_name% > ...";
@ConfigSerializable
public static class Format {
@Comment("The format shown in-game")
@Untranslated(Untranslated.Type.VALUE)
public String format = "";
@Comment("The format when the entity is deleted or can't be looked up")
@Untranslated(Untranslated.Type.VALUE)
public String unknownFormat = "";
@SuppressWarnings("unused") // Configurate
public Format() {}
public Format(String format, String unknownFormat) {
this.format = format;
this.unknownFormat = unknownFormat;
}
}
}
public MentionsConfig mentions = new MentionsConfig();
@Comment("How should unicode emoji be shown in-game:\n"
+ "- hide: hides emojis in-game\n"
@ -100,18 +71,6 @@ public class DiscordToMinecraftChatConfig {
// TODO: add and implement name
}
@Comment("How should custom emoji be shown in-game:\n"
+ "- hide: custom emoji will not be shown in-game\n"
+ "- blank: custom emoji will only be shown in-game if it is rendered by a 3rd party plugin\n"
+ "- name: shows the name of the custom emoji in-game (for example :discordsrv:), unless rendered by a 3rd party plugin")
public EmoteBehaviour customEmojiBehaviour = EmoteBehaviour.BLANK;
public enum EmoteBehaviour {
HIDE,
BLANK,
NAME
}
@Comment("The amount of milliseconds to delay processing Discord messages, if the message is deleted in that time it will not be processed.\n"
+ "This can be used together with Discord moderation bots, to filter forwarded messages")
public long delayMillis = 0L;

View File

@ -0,0 +1,56 @@
package com.discordsrv.common.config.main.generic;
import com.discordsrv.common.config.configurate.annotation.Untranslated;
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
import org.spongepowered.configurate.objectmapping.meta.Comment;
@ConfigSerializable
public class MentionsConfig {
public Format role = new Format(
"%role_color%@%role_name%",
"[color:#5865F2]@deleted-role"
);
public Format channel = new Format(
"[hover:show_text:Click to go to channel][click:open_url:%channel_jump_url%][color:#5865F2]#%channel_name%",
"[color:#5865F2]#Unknown"
);
public Format user = new Format(
"[hover:show_text:Username: @%user_tag%\nRoles: %user_roles:', '|text:'[color:gray][italics:on]None[color][italics]'%][color:#5865F2]@%user_effective_server_name|user_effective_name%",
"[color:#5865F2]@Unknown user"
);
public String messageUrl = "[hover:show_text:Click to go to message][click:open_url:%jump_url%][color:#5865F2]#%channel_name% > ...";
@Comment("How should custom emoji be shown in-game:\n"
+ "- hide: custom emoji will not be shown in-game\n"
+ "- blank: custom emoji will only be shown in-game if it is rendered by a 3rd party plugin\n"
+ "- name: shows the name of the custom emoji in-game (for example :discordsrv:), unless rendered by a 3rd party plugin")
public EmoteBehaviour customEmojiBehaviour = EmoteBehaviour.BLANK;
public enum EmoteBehaviour {
HIDE,
BLANK,
NAME
}
@ConfigSerializable
public static class Format {
@Comment("The format shown in-game")
@Untranslated(Untranslated.Type.VALUE)
public String format = "";
@Comment("The format when the entity is deleted or can't be looked up")
@Untranslated(Untranslated.Type.VALUE)
public String unknownFormat = "";
@SuppressWarnings("unused") // Configurate
public Format() {}
public Format(String format, String unknownFormat) {
this.format = format;
this.unknownFormat = unknownFormat;
}
}
}