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.DiscordSRV;
import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.component.util.ComponentUtil;
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig; import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
import com.discordsrv.common.config.main.generic.MentionsConfig;
import dev.vankka.mcdiscordreserializer.renderer.implementation.DefaultMinecraftRenderer; import dev.vankka.mcdiscordreserializer.renderer.implementation.DefaultMinecraftRenderer;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; 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.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -75,18 +77,32 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
@Override @Override
public Component appendLink(@NotNull Component part, String link) { 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); Matcher matcher = MESSAGE_URL_PATTERN.matcher(link);
if (matcher.matches()) { if (!matcher.matches()) {
return null;
}
String channel = matcher.group(1); String channel = matcher.group(1);
GuildChannel guildChannel = jda.getGuildChannelById(channel); GuildChannel guildChannel = jda.getGuildChannelById(channel);
Context context = CONTEXT.get(); Context context = CONTEXT.get();
String format = context != null ? context.config.mentions.messageUrl : null; String format = context != null ? context.config.mentions.messageUrl : null;
if (format == null || guildChannel == null) { if (format == null || guildChannel == null) {
return super.appendLink(part, link); return null;
} }
return Component.text() return Component.text()
@ -103,47 +119,58 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
) )
.build(); .build();
} }
}
return super.appendLink(part, link);
}
@Override @Override
public @NotNull Component appendChannelMention(@NotNull Component component, @NotNull String id) { public @NotNull Component appendChannelMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get(); 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) { if (format == null) {
return component.append(Component.text("<#" + id + ">")); 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(); JDA jda = discordSRV.jda();
if (jda == null) { if (jda == null) {
return Component.empty(); return null;
} }
GuildChannel guildChannel = jda.getGuildChannelById(id); GuildChannel guildChannel = jda.getGuildChannelById(id);
return component.append(ComponentUtil.fromAPI( return ComponentUtil.fromAPI(
discordSRV.componentFactory() discordSRV.componentFactory()
.textBuilder(guildChannel != null ? format.format : format.unknownFormat) .textBuilder(guildChannel != null ? format.format : format.unknownFormat)
.addContext(guildChannel) .addContext(guildChannel)
.applyPlaceholderService() .applyPlaceholderService()
.build() .build()
)); );
} }
@Override @Override
public @NotNull Component appendUserMention(@NotNull Component component, @NotNull String id) { public @NotNull Component appendUserMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get(); 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; DiscordGuild guild = context != null ? context.guild : null;
if (format == null || guild == null) { if (format == null || guild == null) {
return component.append(Component.text("<@" + id + ">")); return component.append(Component.text("<@" + id + ">"));
} }
long userId = MiscUtil.parseLong(id); long userId = MiscUtil.parseLong(id);
DiscordUser user = discordSRV.discordAPI().getUserById(userId); return component.append(makeUserMention(userId, format, guild));
DiscordGuildMember member = guild.getMemberById(userId); }
@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() GameTextBuilder builder = discordSRV.componentFactory()
.textBuilder(user != null ? format.format : format.unknownFormat); .textBuilder(user != null ? format.format : format.unknownFormat);
@ -155,21 +182,25 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
builder.addContext(member); builder.addContext(member);
} }
return component.append(ComponentUtil.fromAPI( return ComponentUtil.fromAPI(
builder.applyPlaceholderService().build() builder.applyPlaceholderService().build()
)); );
} }
@Override @Override
public @NotNull Component appendRoleMention(@NotNull Component component, @NotNull String id) { public @NotNull Component appendRoleMention(@NotNull Component component, @NotNull String id) {
Context context = CONTEXT.get(); 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) { if (format == null) {
return component.append(Component.text("<#" + id + ">")); return component.append(Component.text("<#" + id + ">"));
} }
long roleId = MiscUtil.parseLong(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() GameTextBuilder builder = discordSRV.componentFactory()
.textBuilder(role != null ? format.format : format.unknownFormat); .textBuilder(role != null ? format.format : format.unknownFormat);
@ -178,9 +209,9 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
builder.addContext(role); builder.addContext(role);
} }
return component.append(ComponentUtil.fromAPI( return ComponentUtil.fromAPI(
builder.applyPlaceholderService().build() builder.applyPlaceholderService().build()
)); );
} }
@Override @Override
@ -190,31 +221,39 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
@NotNull String id @NotNull String id
) { ) {
Context context = CONTEXT.get(); Context context = CONTEXT.get();
DiscordToMinecraftChatConfig.EmoteBehaviour behaviour = context != null ? context.config.customEmojiBehaviour : null; MentionsConfig.EmoteBehaviour behaviour = context != null ? context.config.mentions.customEmojiBehaviour : null;
if (behaviour == null || behaviour == DiscordToMinecraftChatConfig.EmoteBehaviour.HIDE) { if (behaviour == null || behaviour == MentionsConfig.EmoteBehaviour.HIDE) {
return component; return component;
} }
long emojiId = MiscUtil.parseLong(id); long emojiId = MiscUtil.parseLong(id);
DiscordCustomEmoji emoji = discordSRV.discordAPI().getEmojiById(emojiId); Component emoteMention = makeEmoteMention(emojiId, behaviour);
if (emoji == null) { if (emoteMention == null) {
return component; 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); DiscordChatMessageCustomEmojiRenderEvent event = new DiscordChatMessageCustomEmojiRenderEvent(emoji);
discordSRV.eventBus().publish(event); discordSRV.eventBus().publish(event);
if (event.isProcessed()) { if (event.isProcessed()) {
Component rendered = ComponentUtil.fromAPI(event.getRenderedEmojiFromProcessing()); return ComponentUtil.fromAPI(event.getRenderedEmojiFromProcessing());
return component.append(rendered);
} }
switch (behaviour) { switch (behaviour) {
case NAME: case NAME:
return component.append(Component.text(":" + emoji.getName() + ":")); return Component.text(":" + emoji.getName() + ":");
case BLANK: case BLANK:
default: 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.configurate.annotation.Untranslated;
import com.discordsrv.common.config.main.generic.DiscordIgnoresConfig; 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.ConfigSerializable;
import org.spongepowered.configurate.objectmapping.meta.Comment; import org.spongepowered.configurate.objectmapping.meta.Comment;
@ -55,37 +56,7 @@ public class DiscordToMinecraftChatConfig {
public DiscordIgnoresConfig ignores = new DiscordIgnoresConfig(); public DiscordIgnoresConfig ignores = new DiscordIgnoresConfig();
@Comment("The representations of Discord mentions in-game") @Comment("The representations of Discord mentions in-game")
public Mentions mentions = new Mentions(); public MentionsConfig mentions = new MentionsConfig();
@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;
}
}
}
@Comment("How should unicode emoji be shown in-game:\n" @Comment("How should unicode emoji be shown in-game:\n"
+ "- hide: hides emojis in-game\n" + "- hide: hides emojis in-game\n"
@ -100,18 +71,6 @@ public class DiscordToMinecraftChatConfig {
// TODO: add and implement name // 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" @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") + "This can be used together with Discord moderation bots, to filter forwarded messages")
public long delayMillis = 0L; 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;
}
}
}