{
@Override
- public boolean supports(Class super TitleHolder> type) {
+ public boolean supports(Class> type) {
return TitleHolder.class.isAssignableFrom(type);
}
@Override
public void serialize(TitleHolder holder, SerializationData data, GenericsDeclaration generics) {
- if (!holder.getTitle().getRaw().isEmpty()) {
- data.add("title", holder.getTitle().getRaw());
+ Component title = holder.getTitle();
+ if (!title.equals(Component.empty())) {
+ data.set(
+ "title",
+ title,
+ Component.class
+ );
}
- if (!holder.getSubTitle().getRaw().isEmpty()) {
- data.add("subtitle", holder.getSubTitle().getRaw());
+
+ Component subtitle = holder.getSubTitle();
+ if (!subtitle.equals(Component.empty())) {
+ data.set(
+ "subtitle",
+ subtitle,
+ Component.class
+ );
}
Times times = holder.getTimes();
@@ -32,15 +43,27 @@ public void serialize(TitleHolder holder, SerializationData data, GenericsDeclar
int fadeOut = ticksFromDuration(times.fadeOut());
if (fadeIn > 0) {
- data.add("fade-in", fadeIn);
+ data.set(
+ "fade-in",
+ fadeIn,
+ int.class
+ );
}
if (stay > 0) {
- data.add("stay", stay);
+ data.set(
+ "stay",
+ stay,
+ int.class
+ );
}
if (fadeOut > 0) {
- data.add("fade-out", fadeOut);
+ data.set(
+ "fade-out",
+ fadeOut,
+ int.class
+ );
}
}
@@ -49,11 +72,11 @@ public TitleHolder deserialize(DeserializationData data, GenericsDeclaration gen
TitleHolder.Builder builder = TitleHolder.builder();
if (data.containsKey("title")) {
- builder.title(data.get("title", RawComponent.class));
+ builder.title(data.get("title", Component.class));
}
if (data.containsKey("subtitle")) {
- builder.subTitle(data.get("subtitle", RawComponent.class));
+ builder.subTitle(data.get("subtitle", Component.class));
}
int fadeIn = 0;
diff --git a/settings.gradle b/settings.gradle
index a07449a..b07dc7a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,11 +1,11 @@
rootProject.name = 'YetAnotherMessagesLibrary'
+this.setupSubproject("tools")
this.setupSubproject("core")
// Platforms
this.setupSubproject("platform")
this.setupSubproject("platform:bukkit", "platform-bukkit")
-this.setupSubproject("platform:bungee", "platform-bungee")
this.setupSubproject("platform:velocity", "platform-velocity")
// Repositories (Data Supplier)
@@ -33,22 +33,20 @@ dependencyResolutionManagement {
versionCatalogs {
libs {
library("spigot", "org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT")
- library("bungee", "net.md-5:bungeecord-api:1.20-R0.1")
- library("velocity", "com.velocitypowered:velocity-api:3.1.1")
+ library("velocity", "com.velocitypowered:velocity-api:3.4.0-SNAPSHOT")
}
adventure {
- String apiVersion = "4.14.0"
+ String apiVersion = "4.26.1"
library("api", "net.kyori:adventure-api:${apiVersion}")
- library("minimessage", "net.kyori:adventure-text-minimessage:${apiVersion}")
library("serializer-legacy", "net.kyori:adventure-text-serializer-legacy:${apiVersion}")
+ library("serializer-minimessage", "net.kyori:adventure-text-minimessage:${apiVersion}")
- String platformVersion = "4.3.1"
+ String platformVersion = "4.4.1"
library("platform-bukkit", "net.kyori:adventure-platform-bukkit:${platformVersion}")
- library("platform-bungee", "net.kyori:adventure-platform-bungeecord:${platformVersion}")
}
okaeri {
- library("config", "eu.okaeri:okaeri-configs-core:5.0.0-beta.5")
- library("placeholders", "eu.okaeri:okaeri-placeholders-core:4.0.7")
+ library("config", "eu.okaeri:okaeri-configs-core:6.0.0-beta.27")
+ library("placeholders", "eu.okaeri:okaeri-placeholders-core:5.1.2")
}
}
}
diff --git a/tools/build.gradle b/tools/build.gradle
new file mode 100644
index 0000000..f0bf4f3
--- /dev/null
+++ b/tools/build.gradle
@@ -0,0 +1,5 @@
+dependencies {
+ compileOnlyApi adventure.api
+ compileOnlyApi adventure.serializer.legacy
+ compileOnlyApi adventure.serializer.minimessage
+}
\ No newline at end of file
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/GlobalAdventureSerializer.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/GlobalAdventureSerializer.java
new file mode 100644
index 0000000..ced393d
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/GlobalAdventureSerializer.java
@@ -0,0 +1,91 @@
+package dev.peri.yetanothermessageslibrary.adventure;
+
+import dev.peri.yetanothermessageslibrary.replace.replacement.FunctionStringReplacement;
+import dev.peri.yetanothermessageslibrary.replace.replacement.SimpleStringReplacement;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.ComponentSerializer;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Simple utility class to provide global access to adventure serializer.
+ *
+ * This class is used mostly by string replacements ({@link SimpleStringReplacement}, {@link FunctionStringReplacement})
+ * and some of {@link dev.peri.yetanothermessageslibrary.message.holder.SendableHolder} implementations.
+ */
+public final class GlobalAdventureSerializer {
+
+ private static ComponentSerializer GLOBAL_SERIALIZER = new ComponentSerializer() {
+ @Override
+ public @NotNull Component deserialize(@NotNull String input) {
+ return Component.text(input);
+ }
+
+ @Override
+ public @NotNull String serialize(@NotNull Component component) {
+ throw new UnsupportedOperationException("Register global serializer to serialize components");
+ }
+ };
+
+ private GlobalAdventureSerializer() {
+ }
+
+ static {
+ boolean isNativeLegacySerializer = false;
+ boolean isNativeMiniMessageSerializer = false;
+
+ try {
+ Class.forName("net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer");
+ isNativeLegacySerializer = true;
+ } catch (ClassNotFoundException ignored) {
+ }
+
+ try {
+ Class.forName("net.kyori.adventure.text.serializer.minimessage.MiniMessage");
+ isNativeMiniMessageSerializer = true;
+ } catch (ClassNotFoundException ignored) {
+ }
+
+ if (isNativeLegacySerializer) {
+ NativeLegacySerializer.init();
+ } else if (isNativeMiniMessageSerializer) {
+ NativeMiniMessageSerializer.init();
+ }
+ }
+
+ public static @NotNull ComponentSerializer globalSerializer() {
+ return GLOBAL_SERIALIZER;
+ }
+
+ public static void globalSerializer(@NotNull ComponentSerializer globalSerializer) {
+ GLOBAL_SERIALIZER = Objects.requireNonNull(globalSerializer, "globalSerializer cannot be null");
+ }
+
+ public static @NotNull Component deserialize(@NotNull String input) {
+ return GLOBAL_SERIALIZER.deserialize(input);
+ }
+
+ public static @NotNull List deserialize(@NotNull List input) {
+ return input.stream().map(GlobalAdventureSerializer::deserialize).collect(Collectors.toList());
+ }
+
+ public static @NotNull List deserialize(@NotNull String... input) {
+ return deserialize(Arrays.asList(input));
+ }
+
+ public static @NotNull Component[] deserializeArray(@NotNull List input) {
+ return deserialize(input).toArray(new Component[0]);
+ }
+
+ public static @NotNull Component[] deserializeArray(@NotNull String... input) {
+ return deserialize(input).toArray(new Component[0]);
+ }
+
+ public static @NotNull String serialize(@NotNull Component component) {
+ return GLOBAL_SERIALIZER.serialize(component);
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeLegacySerializer.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeLegacySerializer.java
new file mode 100644
index 0000000..970cfa9
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeLegacySerializer.java
@@ -0,0 +1,14 @@
+package dev.peri.yetanothermessageslibrary.adventure;
+
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+
+final class NativeLegacySerializer {
+
+ private NativeLegacySerializer() {
+ }
+
+ static void init() {
+ GlobalAdventureSerializer.globalSerializer(LegacyComponentSerializer.legacySection());
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeMiniMessageSerializer.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeMiniMessageSerializer.java
new file mode 100644
index 0000000..71597e8
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/adventure/NativeMiniMessageSerializer.java
@@ -0,0 +1,14 @@
+package dev.peri.yetanothermessageslibrary.adventure;
+
+import net.kyori.adventure.text.minimessage.MiniMessage;
+
+final class NativeMiniMessageSerializer {
+
+ private NativeMiniMessageSerializer() {
+ }
+
+ static void init() {
+ GlobalAdventureSerializer.globalSerializer(MiniMessage.miniMessage());
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/ComponentReplacer.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/ComponentReplacer.java
new file mode 100644
index 0000000..588a365
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/ComponentReplacer.java
@@ -0,0 +1,69 @@
+package dev.peri.yetanothermessageslibrary.replace;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public final class ComponentReplacer {
+
+ private ComponentReplacer() {
+ }
+
+ @Contract(pure = true, value = "_, null, _ -> null")
+ public static Component replace(@Nullable Locale locale, @Nullable Component text, @NotNull Iterable extends Replaceable> replacements) {
+ if (text == null) {
+ return null;
+ }
+
+ for (Replaceable replacement : replacements) {
+ text = replacement.replace(locale, text);
+ }
+ return text;
+ }
+
+ @Contract(pure = true, value = "null, _, -> null")
+ public static Component replace(@Nullable Component text, @NotNull Iterable extends Replaceable> replacements) {
+ return replace(null, text, replacements);
+ }
+
+ @Contract(pure = true, value = "_, null, _ -> null")
+ public static Component replace(@Nullable Locale locale, @Nullable Component text, @NotNull Replaceable... replacements) {
+ return replace(locale, text, Arrays.asList(replacements));
+ }
+
+ @Contract(pure = true, value = "null, _, -> null")
+ public static Component replace(@Nullable Component text, @NotNull Replaceable... replacements) {
+ return replace(null, text, replacements);
+ }
+
+ @Contract(pure = true)
+ public static @NotNull List replace(@Nullable Locale locale, @NotNull Iterable extends Component> text, @NotNull Iterable extends Replaceable> replacements) {
+ List result = new ArrayList<>();
+ for (Component line : text) {
+ result.add(replace(locale, line, replacements));
+ }
+ return result;
+ }
+
+ @Contract(pure = true)
+ public static @NotNull List replace(@NotNull Iterable extends Component> text, @NotNull Collection extends Replaceable> replacements) {
+ return replace(null, text, replacements);
+ }
+
+ @Contract(pure = true)
+ public static @NotNull List replace(@Nullable Locale locale, @NotNull Iterable extends Component> text, @NotNull Replaceable... replacements) {
+ return replace(locale, text, Arrays.asList(replacements));
+ }
+
+ @Contract(pure = true)
+ public static @NotNull List replace(@NotNull Iterable extends Component> text, @NotNull Replaceable... replacements) {
+ return replace(null, text, replacements);
+ }
+
+}
diff --git a/core/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java
similarity index 70%
rename from core/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java
rename to tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java
index d7cc572..40f562d 100644
--- a/core/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/Replaceable.java
@@ -7,12 +7,6 @@
public interface Replaceable {
- @NotNull String replace(@Nullable Locale locale, @NotNull String text);
-
- default @NotNull String replace(@NotNull String text) {
- return this.replace(null, text);
- }
-
@NotNull Component replace(@Nullable Locale locale, @NotNull Component text);
default @NotNull Component replace(@NotNull Component text) {
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplaceable.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplaceable.java
new file mode 100644
index 0000000..ae0da7c
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplaceable.java
@@ -0,0 +1,15 @@
+package dev.peri.yetanothermessageslibrary.replace;
+
+import java.util.Locale;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface StringReplaceable extends Replaceable {
+
+ @NotNull String replace(@Nullable Locale locale, @NotNull String text);
+
+ default @NotNull String replace(@NotNull String text) {
+ return this.replace(null, text);
+ }
+
+}
diff --git a/core/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java
similarity index 60%
rename from core/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java
rename to tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java
index d8cbe02..b37bfd2 100644
--- a/core/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/StringReplacer.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.jetbrains.annotations.Contract;
@@ -15,35 +14,34 @@ private StringReplacer() {
}
@Contract(pure = true, value = "_, null, _, -> null")
- public static String replace(@Nullable Locale locale, @Nullable String text, @NotNull Collection extends Replaceable> replacements) {
+ public static String replace(@Nullable Locale locale, @Nullable String text, @NotNull Iterable extends StringReplaceable> replacements) {
if (text == null || text.isEmpty()) {
return text;
}
- for (Replaceable replacement : replacements) {
+ for (StringReplaceable replacement : replacements) {
text = replacement.replace(locale, text);
}
-
return text;
}
@Contract(pure = true, value = "null, _, -> null")
- public static String replace(@Nullable String text, @NotNull Collection extends Replaceable> replacements) {
+ public static String replace(@Nullable String text, @NotNull Iterable extends StringReplaceable> replacements) {
return replace(null, text, replacements);
}
@Contract(pure = true, value = "_, null, _, -> null")
- public static String replace(@Nullable Locale locale, @Nullable String text, @NotNull Replaceable... replacements) {
+ public static String replace(@Nullable Locale locale, @Nullable String text, @NotNull StringReplaceable... replacements) {
return replace(locale, text, Arrays.asList(replacements));
}
@Contract(pure = true, value = "null, _, -> null")
- public static String replace(@Nullable String text, @NotNull Replaceable... replacements) {
+ public static String replace(@Nullable String text, @NotNull StringReplaceable... replacements) {
return replace(null, text, replacements);
}
@Contract(pure = true)
- public static @NotNull List replace(@Nullable Locale locale, @NotNull List text, @NotNull Replaceable... replacements) {
+ public static @NotNull List replace(@Nullable Locale locale, @NotNull Iterable text, @NotNull Iterable extends StringReplaceable> replacements) {
List result = new ArrayList<>();
for (String line : text) {
result.add(replace(locale, line, replacements));
@@ -52,8 +50,18 @@ public static String replace(@Nullable String text, @NotNull Replaceable... repl
}
@Contract(pure = true)
- public static @NotNull List replace(@NotNull List text, @NotNull Replaceable... replacements) {
+ public static @NotNull List replace(@NotNull Iterable text, @NotNull Iterable extends StringReplaceable> replacements) {
return replace(null, text, replacements);
}
+ @Contract(pure = true)
+ public static @NotNull List replace(@NotNull Iterable text, @NotNull StringReplaceable... replacements) {
+ return replace(null, text, Arrays.asList(replacements));
+ }
+
+ @Contract(pure = true)
+ public static @NotNull List replace(@Nullable Locale locale, @NotNull Iterable text, @NotNull StringReplaceable... replacements) {
+ return replace(locale, text, Arrays.asList(replacements));
+ }
+
}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/ComponentReplacement.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/ComponentReplacement.java
new file mode 100644
index 0000000..6dbf489
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/ComponentReplacement.java
@@ -0,0 +1,22 @@
+package dev.peri.yetanothermessageslibrary.replace.replacement;
+
+import java.util.Locale;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TextReplacementConfig;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class ComponentReplacement extends Replacement {
+
+ protected ComponentReplacement(@NotNull Object placeholder) {
+ super(placeholder);
+ }
+
+ public abstract @NotNull TextReplacementConfig getReplacement(@Nullable Locale locale);
+
+ @Override
+ public @NotNull Component replace(@Nullable Locale locale, @NotNull Component text) {
+ return text.replaceText(this.getReplacement(locale));
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionReplacement.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionReplacement.java
new file mode 100644
index 0000000..b23a812
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionReplacement.java
@@ -0,0 +1,31 @@
+package dev.peri.yetanothermessageslibrary.replace.replacement;
+
+import java.util.Locale;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import net.kyori.adventure.text.ComponentLike;
+import net.kyori.adventure.text.TextReplacementConfig;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FunctionReplacement extends ComponentReplacement {
+
+ private final Function<@Nullable Locale, ? extends @NotNull ComponentLike> replacementFunction;
+
+ protected FunctionReplacement(@NotNull Object placeholder, @NotNull Function<@Nullable Locale, ? extends @NotNull ComponentLike> replacementFunction) {
+ super(placeholder);
+ this.replacementFunction = replacementFunction;
+ }
+
+ protected FunctionReplacement(@NotNull Object placeholder, @NotNull Supplier extends @NotNull ComponentLike> replacementSupplier) {
+ this(placeholder, locale -> replacementSupplier.get());
+ }
+
+ @Override
+ public @NotNull TextReplacementConfig getReplacement(@Nullable Locale locale) {
+ return this.newReplacementBuilder()
+ .replacement(this.replacementFunction.apply(locale))
+ .build();
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionStringReplacement.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionStringReplacement.java
new file mode 100644
index 0000000..a0f52b0
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/FunctionStringReplacement.java
@@ -0,0 +1,30 @@
+package dev.peri.yetanothermessageslibrary.replace.replacement;
+
+import dev.peri.yetanothermessageslibrary.adventure.GlobalAdventureSerializer;
+import dev.peri.yetanothermessageslibrary.replace.StringReplaceable;
+import java.util.Locale;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FunctionStringReplacement extends FunctionReplacement implements StringReplaceable {
+
+ private final Function<@Nullable Locale, ? extends @NotNull String> replacementFunction;
+
+ protected FunctionStringReplacement(@NotNull Object placeholder, @NotNull Function<@Nullable Locale, @NotNull String> replacementFunction) {
+ super(placeholder, locale -> GlobalAdventureSerializer.deserialize(replacementFunction.apply(locale)));
+ this.replacementFunction = replacementFunction;
+ }
+
+ protected FunctionStringReplacement(@NotNull Object placeholder, @NotNull Supplier<@NotNull String> replacementSupplier) {
+ super(placeholder, locale -> GlobalAdventureSerializer.deserialize(replacementSupplier.get()));
+ this.replacementFunction = locale -> replacementSupplier.get();
+ }
+
+ @Override
+ public @NotNull String replace(@Nullable Locale locale, @NotNull String text) {
+ return this.getPlaceholderType().replace(text, this.getPlaceholder(), this.replacementFunction.apply(locale));
+ }
+
+}
diff --git a/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/Replacement.java b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/Replacement.java
new file mode 100644
index 0000000..2b86808
--- /dev/null
+++ b/tools/src/main/java/dev/peri/yetanothermessageslibrary/replace/replacement/Replacement.java
@@ -0,0 +1,155 @@
+package dev.peri.yetanothermessageslibrary.replace.replacement;
+
+import dev.peri.yetanothermessageslibrary.replace.Replaceable;
+import dev.peri.yetanothermessageslibrary.util.TriFunction;
+import dev.peri.yetanothermessageslibrary.util.Validate;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.regex.Pattern;
+import net.kyori.adventure.text.ComponentLike;
+import net.kyori.adventure.text.TextReplacementConfig;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class Replacement implements Replaceable {
+
+ private final PlaceholderType placeholderType;
+ private final Object placeholder;
+
+ protected Replacement(@NotNull Object placeholder) {
+ PlaceholderType placeholderType = PlaceholderType.findType(placeholder.getClass());
+ Validate.isTrue(placeholderType != null, "placeholder must be a String or Pattern");
+ this.placeholderType = placeholderType;
+ this.placeholder = placeholder;
+ }
+
+ /**
+ * @return the type of placeholder (String or Pattern)
+ */
+ protected final @NotNull Replacement.PlaceholderType getPlaceholderType() {
+ return this.placeholderType;
+ }
+
+ /**
+ * @return a new TextReplacementConfig.Builder that matches the placeholder
+ */
+ protected final @NotNull TextReplacementConfig.Builder newReplacementBuilder() {
+ return this.placeholderType.newReplacementBuilder(this.placeholder);
+ }
+
+ /**
+ * @return the placeholder object to match (String or Pattern)
+ */
+ protected final @NotNull Object getPlaceholder() {
+ return this.placeholder;
+ }
+
+ protected enum PlaceholderType {
+
+ STRING(
+ String.class,
+ (text, placeholder, replacement) -> text.replace((String) placeholder, replacement),
+ replacement -> TextReplacementConfig.builder().matchLiteral((String) replacement)
+ ),
+ REGEX(
+ Pattern.class,
+ (text, placeholder, replacement) -> ((Pattern) placeholder).matcher(text).replaceAll(replacement),
+ replacement -> TextReplacementConfig.builder().match((Pattern) replacement)
+ );
+
+ private static final Map, PlaceholderType> PLACEHOLDERS_MAP;
+
+ static {
+ Map, PlaceholderType> map = new HashMap<>();
+ for (PlaceholderType placeholderType : PlaceholderType.values()) {
+ map.put(placeholderType.getClazz(), placeholderType);
+ }
+ PLACEHOLDERS_MAP = Collections.unmodifiableMap(map);
+ }
+
+ private final Class> clazz;
+ private final TriFunction replacer;
+ private final Function