When Giving MiniMessage to players
If either, you are using skript to format your chat/using a chat plugin/did your own chat on Java/Kotlin and you give people to use MiniMessage, you need to filter it because you can use: run_command to trick people to pay someone money, or an admin to run it to run dangerous commands, <newline> to give a new line and make it annoying to people! (including others)
What type of MiniMessages?
<run_command>Runs the command (you can set a trap for anything normal, and then you can put for example, to pay someone 1k, or to give someone operator or use luckperms or whatever)<newline>Gives a new line<click:open_url>Wraps the link to a normal looking message, hovering over it will open the link (and give you a warning obviously), which it miiiiight be used for someone to fell to like, an IP logger, or scam
How do you avoid them?
If you own the Chat Plugin
This varies if you are using Java/Kotlin/Skript
You can do it before or after, whoever is uh best for you
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import java.util.regex.Pattern;
public class mmFilter {
private static final Pattern[] NuhUh = {
Pattern.compile("</?click[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("</?hover[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("</?newline>", Pattern.CASE_INSENSITIVE),
};
public static String stripBefore(String input) {
if (input == null || input.isEmpty()) return input;
String result = input;
for (Pattern p : NuhUh) {
result = p.matcher(result).replaceAll("");
}
return result;
}
public static Component stripAfter(Component component) {
return component.replaceChildren(child -> {
if (child.clickEvent() != null) child = child.clickEvent(null);
if (child.hoverEvent() != null) child = child.hoverEvent(null);
child = child.replaceChildren(stripAfter(child));
return child;
});
}
}
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TextComponent
import java.util.regex.Pattern
object mmFilter {
private val NuhUh = listOf(
Pattern.compile("</?click[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("</?hover[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("</?newline>", Pattern.CASE_INSENSITIVE),
)
fun stripBefore(input: String?): String? {
if (input.isNullOrBlank()) return input
var result = input
for (p in NuhUh) {
result = p.matcher(result!!).replaceAll("")
}
return result
}
fun stripAfter(component: Component): Component {
val result = component
.clickEvent(null)
.hoverEvent(null)
val children = result.children().map { stripAfter(it) }
@Suppress("UNCHECKED_CAST")
return (result as TextComponent).children(children)
}
}
on chat:
set {_input} to message
replace all regex "</?click[^>]*>" with "" in {_input}
replace all regex "</?hover[^>]*>" with "" in {_input}
replace all regex "</?newline>" with "" in {_input}
set message to {_input}
If using a Chat Plugin
If the chat plugin has disallowed those MiniMessages, then you're good, but if it is not and it is added to a new version, update your plugin!
If that plugin allows you what type of MiniMessage it can be sent, disable those
If however, it gives minimessage BUT it cannot be controlled, then you need to put a Skript/ConditionalEvents thing that does this for you, i guess
on chat:
set {_input} to message
if {_input} partially matches "</?(click|hover|newline)[^>]*>":
cancel event
send "&cYou cannot send that!"
mm_nuhuh:
type: player_chat
conditions:
- '%message% matches </?(click|hover|newline)[^>]*>'
actions:
default:
- 'cancel_event: true'
- 'message: &cYou cannot send that!'