24package com.dreamfirestudios.dreamcore.DreamChat;
26import me.clip.placeholderapi.PlaceholderAPI;
27import net.kyori.adventure.text.Component;
28import net.kyori.adventure.text.minimessage.MiniMessage;
29import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
30import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
31import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
32import org.bukkit.Bukkit;
33import org.bukkit.entity.Player;
34import org.jetbrains.annotations.NotNull;
35import org.jetbrains.annotations.Nullable;
37import java.util.Locale;
38import java.util.Objects;
39import java.util.regex.Pattern;
57 private static final MiniMessage MM = MiniMessage.miniMessage();
60 private static final Pattern COLOR_TAGS = Pattern.compile(
61 "</?#[0-9a-fA-F]{6}>|</?color(?:\\s*:\\s*#[0-9a-fA-F]{6})?>|</?gradient(?:\\s*:[^>]+)?>|</?rainbow(?:\\s*:[^>]+)?>"
63 private static final Pattern FORMAT_TAGS = Pattern.compile(
64 "</?(bold|b|italic|i|underlined|u|strikethrough|st|obfuscated|obf)>"
66 private static final Pattern ACTION_TAGS = Pattern.compile(
67 "</?click(?:\\s*:[^>]+)?>|</?hover(?:\\s*:[^>]+)?>"
80 public static @NotNull Component
format(@Nullable String message,
82 return format(message,
null, settings);
93 public static @NotNull Component
format(@Nullable String message,
94 @Nullable Player player,
96 TagResolver... resolvers) {
97 if (message ==
null)
return Component.empty();
100 String processed = message;
101 if (s.usePlaceholders() && player !=
null && isPapiAvailable()) {
102 processed = PlaceholderAPI.setPlaceholders(player, processed);
105 if (!s.allowMiniMessage()) {
107 processed = sanitize(processed, s);
108 return Component.text(processed);
111 processed = sanitize(processed, s);
112 final TagResolver resolver = (resolvers !=
null && resolvers.length > 0)
113 ? TagResolver.resolver(resolvers)
114 : TagResolver.empty();
115 return MM.deserialize(processed, resolver);
125 public static @NotNull Component
format(@Nullable String message,
126 @Nullable Player player,
128 return format(message, player, settings, TagResolver.empty());
143 public static @NotNull Component
format(@Nullable Component component,
145 return format(component,
null, settings, TagResolver.empty());
156 public static @NotNull Component
format(@Nullable Component component,
157 @Nullable Player player,
159 TagResolver... resolvers) {
160 if (component ==
null)
return Component.empty();
164 if (!s.allowMiniMessage() && !(s.usePlaceholders() && player !=
null && isPapiAvailable())) {
169 String mm = MM.serialize(component);
171 if (s.usePlaceholders() && player !=
null && isPapiAvailable()) {
172 mm = PlaceholderAPI.setPlaceholders(player, mm);
175 mm = sanitize(mm, s);
177 final TagResolver resolver = (resolvers !=
null && resolvers.length > 0)
178 ? TagResolver.resolver(resolvers)
179 : TagResolver.empty();
181 return MM.deserialize(mm, resolver);
194 public static @Nullable String
centerMessage(@Nullable String message,
int width) {
195 if (message ==
null)
return null;
196 final int w = Math.max(width, message.length());
197 final int pad = w - message.length();
198 final int left = pad / 2;
199 final int right = pad - left;
200 return " ".repeat(left) + message +
" ".repeat(right);
210 public static @NotNull Component
centerMessage(@NotNull Component component,
int width) {
211 final String plain = PlainTextComponentSerializer.plainText().serialize(component);
213 return Component.text(centered ==
null ?
"" : centered);
222 public static @NotNull String
limitMessage(@Nullable String message,
int maxLen) {
223 if (message ==
null || maxLen <= 0)
return "...";
224 if (message.length() <= maxLen)
return message;
225 return message.substring(0, Math.max(0, maxLen)) +
"...";
234 public static @NotNull Component
limitMessage(@NotNull Component component,
int maxLen) {
235 final String plain = PlainTextComponentSerializer.plainText().serialize(component);
245 if (message ==
null || message.isEmpty())
return message;
246 String[] words = message.split(
" ");
247 StringBuilder sb =
new StringBuilder(message.length());
248 for (String w : words) {
249 if (w.isEmpty())
continue;
250 sb.append(Character.toUpperCase(w.charAt(0)))
251 .append(w.substring(1).toLowerCase(Locale.ROOT))
254 return sb.toString().trim();
263 if (message ==
null)
return null;
264 return new StringBuilder(message).reverse().toString();
277 public static @NotNull TagResolver
placeholder(@NotNull String key, @Nullable String value) {
278 return Placeholder.unparsed(key, value ==
null ?
"" : value);
287 public static @NotNull TagResolver
placeholder(@NotNull String key, @NotNull Component value) {
288 return Placeholder.component(key, value);
298 private static boolean isPapiAvailable() {
299 return Bukkit.getPluginManager().isPluginEnabled(
"PlaceholderAPI");
316 private static @NotNull String sanitize(@NotNull String input, @NotNull
DreamMessageSettings s) {
318 if (!s.allowColors()) {
319 out = COLOR_TAGS.matcher(out).replaceAll(
"");
321 if (!s.allowFormatting()) {
322 out = FORMAT_TAGS.matcher(out).replaceAll(
"");
324 if (!s.allowClickAndHover()) {
325 out = ACTION_TAGS.matcher(out).replaceAll(
"");
record DreamMessageSettings(boolean usePlaceholders, boolean allowMiniMessage, boolean allowColors, boolean allowFormatting, boolean allowClickAndHover)
Immutable settings that control how DreamMessageFormatter processes messages.