From 62de0836908ba43b3f11e94daeaeab53dcb2f483 Mon Sep 17 00:00:00 2001 From: TehBrian Date: Sat, 25 May 2024 23:58:31 -0400 Subject: [PATCH] add markdown chat formatting --- .../java/city/thefloating/helios/Helios.java | 2 + .../helios/server/ChatListener.java | 33 ++++++++++++++- .../helios/server/MarkdownCommand.java | 42 +++++++++++++++++++ .../city/thefloating/helios/soul/Charon.java | 5 ++- .../city/thefloating/helios/soul/Otzar.java | 3 +- .../city/thefloating/helios/soul/Soul.java | 12 ++++++ src/main/resources/lang.conf | 5 +++ 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/main/java/city/thefloating/helios/server/MarkdownCommand.java diff --git a/src/main/java/city/thefloating/helios/Helios.java b/src/main/java/city/thefloating/helios/Helios.java index 72c99e6..6c80f7d 100644 --- a/src/main/java/city/thefloating/helios/Helios.java +++ b/src/main/java/city/thefloating/helios/Helios.java @@ -41,6 +41,7 @@ import city.thefloating.helios.server.HeliosCommand; import city.thefloating.helios.server.GameModeCommands; import city.thefloating.helios.server.JoinQuitListener; +import city.thefloating.helios.server.MarkdownCommand; import city.thefloating.helios.server.RulesCommand; import city.thefloating.helios.server.ServerPingListener; import city.thefloating.helios.server.VoteCommand; @@ -205,6 +206,7 @@ private boolean initCommands() { this.injector.getInstance(GameModeCommands.class).register(this.commandManager); this.injector.getInstance(HatCommand.class).register(this.commandManager); this.injector.getInstance(MilkCommand.class).register(this.commandManager); + this.injector.getInstance(MarkdownCommand.class).register(this.commandManager); this.injector.getInstance(NextbotCommand.class).register(this.commandManager); this.injector.getInstance(PackCommand.class).register(this.commandManager); this.injector.getInstance(PianoCommand.class).register(this.commandManager); diff --git a/src/main/java/city/thefloating/helios/server/ChatListener.java b/src/main/java/city/thefloating/helios/server/ChatListener.java index 8b08584..dba2229 100644 --- a/src/main/java/city/thefloating/helios/server/ChatListener.java +++ b/src/main/java/city/thefloating/helios/server/ChatListener.java @@ -4,6 +4,7 @@ import city.thefloating.helios.Permission; import city.thefloating.helios.config.EmotesConfig; import city.thefloating.helios.config.LangConfig; +import city.thefloating.helios.soul.Charon; import com.google.inject.Inject; import io.papermc.paper.event.player.AsyncChatDecorateEvent; import io.papermc.paper.event.player.AsyncChatEvent; @@ -11,6 +12,7 @@ import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Sound; @@ -32,14 +34,17 @@ public final class ChatListener implements Listener { private final EmotesConfig emotesConfig; private final LangConfig langConfig; + private final Charon charon; @Inject public ChatListener( final EmotesConfig emotesConfig, - final LangConfig langConfig + final LangConfig langConfig, + final Charon charon ) { this.emotesConfig = emotesConfig; this.langConfig = langConfig; + this.charon = charon; } @EventHandler @@ -51,6 +56,7 @@ public void onDecorate(final AsyncChatDecorateEvent event) { } event.result(this.colorCodes(event.result(), source)); + event.result(this.markdown(event.result(), source)); event.result(this.colorPingedPlayers(event.result(), source)); event.result(this.replaceEmotes(event.result())); event.result(this.greentext(event.result())); // greentext last to overwrite all other colors. @@ -84,6 +90,31 @@ private Component greentext(final Component component) { return component; } + private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*(.*)\\*\\*"); + private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*(.*?)\\*"); + private static final Pattern UNDERLINED_PATTERN = Pattern.compile("__(.*)__"); + private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~(.*)~~"); + + private Component markdown(final Component component, final Player source) { + if (!this.charon.grab(source).markdown()) { + return component; + } + + return component + .replaceText(t -> t + .match(BOLD_PATTERN) + .replacement((m, b) -> Component.text(m.group(1)).decorate(TextDecoration.BOLD))) + .replaceText(t -> t + .match(ITALIC_PATTERN) + .replacement((m, b) -> Component.text(m.group(1)).decorate(TextDecoration.ITALIC))) + .replaceText(t -> t + .match(UNDERLINED_PATTERN) + .replacement((m, b) -> Component.text(m.group(1)).decorate(TextDecoration.UNDERLINED))) + .replaceText(t -> t + .match(STRIKETHROUGH_PATTERN) + .replacement((m, b) -> Component.text(m.group(1)).decorate(TextDecoration.STRIKETHROUGH))); + } + private Component colorPingedPlayers(final Component component, final Player source) { Component result = component; diff --git a/src/main/java/city/thefloating/helios/server/MarkdownCommand.java b/src/main/java/city/thefloating/helios/server/MarkdownCommand.java new file mode 100644 index 0000000..8b598b8 --- /dev/null +++ b/src/main/java/city/thefloating/helios/server/MarkdownCommand.java @@ -0,0 +1,42 @@ +package city.thefloating.helios.server; + +import city.thefloating.helios.config.LangConfig; +import city.thefloating.helios.soul.Charon; +import cloud.commandframework.meta.CommandMeta; +import cloud.commandframework.paper.PaperCommandManager; +import com.google.inject.Inject; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.spongepowered.configurate.NodePath; + +public class MarkdownCommand { + + private final LangConfig langConfig; + private final Charon charon; + + @Inject + public MarkdownCommand( + final LangConfig langConfig, + final Charon charon + ) { + this.langConfig = langConfig; + this.charon = charon; + } + + public void register(final PaperCommandManager commandManager) { + final var main = commandManager.commandBuilder("markdown") + .meta(CommandMeta.DESCRIPTION, "Toggle markdown chat formatting.") + .senderType(Player.class) + .handler(c -> { + final Player sender = (Player) c.getSender(); + if (this.charon.grab(sender).toggleMarkdown()) { + sender.sendMessage(this.langConfig.c(NodePath.path("markdown", "enabled"))); + } else { + sender.sendMessage(this.langConfig.c(NodePath.path("markdown", "disabled"))); + } + }); + + commandManager.command(main); + } + +} diff --git a/src/main/java/city/thefloating/helios/soul/Charon.java b/src/main/java/city/thefloating/helios/soul/Charon.java index f782c17..2667bcf 100644 --- a/src/main/java/city/thefloating/helios/soul/Charon.java +++ b/src/main/java/city/thefloating/helios/soul/Charon.java @@ -30,6 +30,9 @@ public Soul grab(final UUID uuid) { if (spirit.netherInfractions() != null) { soul.netherInfractions(spirit.netherInfractions()); } + if (spirit.markdown() != null) { + soul.markdown(spirit.markdown()); + } } return soul; }); @@ -41,7 +44,7 @@ public Soul grab(final Player player) { public void save() throws ConfigurateException { for (final var soul : this.souls.values()) { - final var spirit = new Otzar.Data.Spirit(soul.netherInfractions()); + final var spirit = new Otzar.Data.Spirit(soul.netherInfractions(), soul.markdown()); this.otzar.spirits().put(soul.getUuid(), spirit); } this.otzar.save(); diff --git a/src/main/java/city/thefloating/helios/soul/Otzar.java b/src/main/java/city/thefloating/helios/soul/Otzar.java index 2ba790f..50a2519 100644 --- a/src/main/java/city/thefloating/helios/soul/Otzar.java +++ b/src/main/java/city/thefloating/helios/soul/Otzar.java @@ -47,7 +47,8 @@ protected Class getDataClass() { public record Data(Map spirits) { @ConfigSerializable - public record Spirit(Integer netherInfractions) { + public record Spirit(Integer netherInfractions, + Boolean markdown) { } diff --git a/src/main/java/city/thefloating/helios/soul/Soul.java b/src/main/java/city/thefloating/helios/soul/Soul.java index d886e34..c76e091 100644 --- a/src/main/java/city/thefloating/helios/soul/Soul.java +++ b/src/main/java/city/thefloating/helios/soul/Soul.java @@ -10,6 +10,7 @@ public final class Soul { private boolean flyBypassEnabled = false; private int netherInfractions = 0; + private boolean markdown = true; private boolean elevatorMusicPlaying = false; private final Piano piano = new Piano(false, Instrument.HARP); @@ -43,6 +44,17 @@ public void netherInfractions(final int netherBlindnessCount) { this.netherInfractions = netherBlindnessCount; } + public boolean markdown() { return this.markdown; } + + public void markdown(final boolean markdown) { + this.markdown = markdown; + } + + public boolean toggleMarkdown() { + this.markdown(!this.markdown()); + return this.markdown(); + } + public boolean elevatorMusicPlaying() { return this.elevatorMusicPlaying; } diff --git a/src/main/resources/lang.conf b/src/main/resources/lang.conf index 2a414d0..c85b495 100644 --- a/src/main/resources/lang.conf +++ b/src/main/resources/lang.conf @@ -1,6 +1,11 @@ banner: "-=-=-=-=-=-=-=-[ -=[ <#55AAFF>The <#55FFFF>Floating <#55FFAA>City ]=- ]-=-=-=-=-=-=-=-" chat-format: ": " +markdown: { + enabled: "Markdown formatting has been enabled." + disabled: "Markdown formatting has been disabled." +} + motd: "» Welcome back! You were last on <#99FFFF> ago." motd-new: "» Welcome to the server, ! Before building, please read the /rules."