From 8aee8eef828ecfe577645bd31fc552f069b9390a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:18:00 +0000 Subject: [PATCH 1/3] Initial plan From bb62e3989daab7708046652369e637fe77eb17c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:24:28 +0000 Subject: [PATCH 2/3] Add MineDown support for Markdown-like formatting in player messages Co-authored-by: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> --- buildSrc/src/main/kotlin/eternalcode.java.gradle.kts | 1 + chatformatter-core/build.gradle.kts | 4 ++++ .../com/eternalcode/formatter/ChatHandlerImpl.java | 10 +++++++++- .../java/com/eternalcode/formatter/ChatSettings.java | 2 ++ .../com/eternalcode/formatter/config/PluginConfig.java | 9 +++++++++ gradlew | 0 6 files changed, 25 insertions(+), 1 deletion(-) mode change 100644 => 100755 gradlew diff --git a/buildSrc/src/main/kotlin/eternalcode.java.gradle.kts b/buildSrc/src/main/kotlin/eternalcode.java.gradle.kts index 927d8615..41840b28 100644 --- a/buildSrc/src/main/kotlin/eternalcode.java.gradle.kts +++ b/buildSrc/src/main/kotlin/eternalcode.java.gradle.kts @@ -14,6 +14,7 @@ repositories { maven { url = uri("https://jitpack.io") } maven { url = uri("https://repo.eternalcode.pl/releases") } maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/") + maven { url = uri("https://repo.minebench.de/") } } java { diff --git a/chatformatter-core/build.gradle.kts b/chatformatter-core/build.gradle.kts index 1da97d7c..898ac15a 100644 --- a/chatformatter-core/build.gradle.kts +++ b/chatformatter-core/build.gradle.kts @@ -33,6 +33,9 @@ dependencies { // GitCheck implementation("com.eternalcode:gitcheck:1.0.0") + // MineDown + implementation("de.themoep:minedown-adventure:1.7.6-SNAPSHOT") + // JUnit 5 testImplementation(platform("org.junit:junit-bom:6.0.2")) testImplementation("org.junit.jupiter:junit-jupiter-api") @@ -72,6 +75,7 @@ tasks { "net.kyori", "org.bstats", "org.json", + "de.themoep.minedown", ).forEach { pack -> relocate(pack, "$prefix.$pack") } diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java index 0b82fb04..b0a170a6 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java @@ -1,6 +1,7 @@ package com.eternalcode.formatter; import com.eternalcode.formatter.adventure.AdventureUrlPostProcessor; +import de.themoep.minedown.adventure.MineDown; import java.util.Optional; import net.kyori.adventure.text.serializer.json.JSONOptions; import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; @@ -137,7 +138,14 @@ private TagResolver.Single namePlaceholder(Player sender) { private TagResolver.Single messagePlaceholder(Player sender, String rawMessage) { TagResolver permittedTags = this.providePermittedTags(sender); rawMessage = Legacy.legacyToAdventure(rawMessage, permission -> sender.hasPermission(permission)); - Component componentMessage = EMPTY_MESSAGE_DESERIALIZER.deserialize(rawMessage, permittedTags); + + Component componentMessage; + if (this.settings.isMineDownEnabled()) { + componentMessage = MineDown.parse(rawMessage); + } else { + componentMessage = EMPTY_MESSAGE_DESERIALIZER.deserialize(rawMessage, permittedTags); + } + return Placeholder.component("message", componentMessage); } diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatSettings.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatSettings.java index db5805fe..4a5ba28d 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatSettings.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatSettings.java @@ -4,6 +4,8 @@ public interface ChatSettings { boolean isReceiveUpdates(); + boolean isMineDownEnabled(); + String getRawFormat(String rank); } diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/config/PluginConfig.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/config/PluginConfig.java index 90ca6989..ab26642e 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/config/PluginConfig.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/config/PluginConfig.java @@ -23,6 +23,10 @@ public class PluginConfig implements ChatSettings, TemplateRepository { @Description({ " ", "# Do you want to receive updates about new versions of ChatFormatter?" }) public boolean receiveUpdates = true; + @Description({ " ", "# Do you want to enable MineDown support? (Markdown-like formatting for Minecraft)", + "# See https://github.com/Phoenix616/MineDown for more information." }) + public boolean mineDownSupport = false; + @Description({ " ", "# Chat format for ranks (Vault) Support mini-messages and legacy colors" }) @Description({ " ", "# We're recommending to use webui for mini-messages: https://webui.adventure.kyori.net/" }) @@ -89,6 +93,11 @@ public boolean isReceiveUpdates() { return this.receiveUpdates; } + @Override + public boolean isMineDownEnabled() { + return this.mineDownSupport; + } + @Override public String getRawFormat(String rank) { return this.format.getOrDefault(rank, this.defaultFormat); diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 62ace9fc2b3a2998f8659ce3e68b6439b167bd10 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:26:04 +0000 Subject: [PATCH 3/3] Address review: add permission checks and fix legacy color handling for MineDown Co-authored-by: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> --- .../formatter/ChatHandlerImpl.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java index b0a170a6..f55777fc 100644 --- a/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java +++ b/chatformatter-core/src/main/java/com/eternalcode/formatter/ChatHandlerImpl.java @@ -2,6 +2,7 @@ import com.eternalcode.formatter.adventure.AdventureUrlPostProcessor; import de.themoep.minedown.adventure.MineDown; +import de.themoep.minedown.adventure.MineDownParser; import java.util.Optional; import net.kyori.adventure.text.serializer.json.JSONOptions; import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; @@ -136,13 +137,27 @@ private TagResolver.Single namePlaceholder(Player sender) { } private TagResolver.Single messagePlaceholder(Player sender, String rawMessage) { - TagResolver permittedTags = this.providePermittedTags(sender); - rawMessage = Legacy.legacyToAdventure(rawMessage, permission -> sender.hasPermission(permission)); - Component componentMessage; + if (this.settings.isMineDownEnabled()) { - componentMessage = MineDown.parse(rawMessage); + MineDown mineDown = new MineDown(rawMessage); + + if (!sender.hasPermission(PERMISSION_ALL)) { + if (!sender.hasPermission("chatformatter.decorations.*")) { + mineDown.disable(MineDownParser.Option.SIMPLE_FORMATTING); + } + if (!(sender.hasPermission("chatformatter.hover") && sender.hasPermission("chatformatter.click"))) { + mineDown.disable(MineDownParser.Option.ADVANCED_FORMATTING); + } + if (!sender.hasPermission("chatformatter.color.*")) { + mineDown.disable(MineDownParser.Option.LEGACY_COLORS); + } + } + + componentMessage = mineDown.toComponent(); } else { + TagResolver permittedTags = this.providePermittedTags(sender); + rawMessage = Legacy.legacyToAdventure(rawMessage, permission -> sender.hasPermission(permission)); componentMessage = EMPTY_MESSAGE_DESERIALIZER.deserialize(rawMessage, permittedTags); }