diff --git a/build.gradle.kts b/build.gradle.kts
index eec54f2..56933b0 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -14,12 +14,16 @@ description = "An awesome placeholder provider!"
repositories {
mavenCentral()
mavenLocal()
+
+ maven {
+ url = uri("https://repo.codemc.io/repository/hytale/")
+ }
}
dependencies {
implementation("org.yaml:snakeyaml:2.5")
- compileOnly(files("libs/HytaleServer.jar"))
+ compileOnly("com.hypixel.hytale:Server:2026.01.17-4b0f30090")
compileOnlyApi("org.jetbrains:annotations:23.0.0")
}
diff --git a/src/main/java/at/helpch/placeholderapi/PlaceholderAPI.java b/src/main/java/at/helpch/placeholderapi/PlaceholderAPI.java
index 62f5cb8..499fade 100644
--- a/src/main/java/at/helpch/placeholderapi/PlaceholderAPI.java
+++ b/src/main/java/at/helpch/placeholderapi/PlaceholderAPI.java
@@ -31,10 +31,12 @@ import java.util.stream.Collectors;
import at.helpch.placeholderapi.expansion.PlaceholderExpansion;
import at.helpch.placeholderapi.expansion.Relational;
import at.helpch.placeholderapi.replacer.CharsReplacer;
+import at.helpch.placeholderapi.replacer.MessageReplacer;
import at.helpch.placeholderapi.replacer.Replacer;
import at.helpch.placeholderapi.replacer.Replacer.Closure;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.entity.entities.Player;
+import com.hypixel.hytale.server.core.universe.PlayerRef;
import org.jetbrains.annotations.NotNull;
public final class PlaceholderAPI {
@@ -62,48 +64,26 @@ public final class PlaceholderAPI {
* @return String containing all translated placeholders
*/
@NotNull
- public static String setPlaceholders(final Player player,
+ public static String setPlaceholders(final PlayerRef player,
@NotNull final String text) {
return REPLACER_PERCENT.apply(text, player,
PlaceholderAPIPlugin.instance().localExpansionManager()::getExpansion);
}
- public static Message setPlaceholders(final Player player,
+ /**
+ * Translates all placeholders into their corresponding values.
+ *
The pattern of a valid placeholder is {@literal %_%}.
+ *
+ * @param player Player to parse the placeholders against
+ * @param original Message to set the placeholder values in
+ * @return Message containing all translated placeholders
+ */
+ @NotNull
+ public static Message setPlaceholders(final PlayerRef player,
@NotNull final Message original) {
- String replaced = setPlaceholders(player, original.getFormattedMessage().rawText);
- String link = original.getFormattedMessage().link == null ? null : PlaceholderAPI.setPlaceholders(player, original.getFormattedMessage().link);
-
- List newChildren = original.getChildren().stream()
- .filter(Objects::nonNull)
- .map(child -> setPlaceholders(player, child))
- .toList();
-
- Message message = Message.raw(replaced)
- .color(original.getColor());
-
- if (link != null) {
- message = message.link(link);
- }
-
- int bold = original.getFormattedMessage().bold.getValue();
- if (bold != 0) {
- message = message.bold(bold != 1);
- }
-
- int italic = original.getFormattedMessage().italic.getValue();
- if (italic != 0) {
- message = message.italic(italic != 1);
- }
-
- return message.insertAll(newChildren);
+ return MessageReplacer.replace(original, str -> setPlaceholders(player, str));
}
-// @NotNull
-// public static Message setPlaceholders(final Player player,
-// @NotNull final Message message) {
-//
-// }
-
/**
* Translates all placeholders into their corresponding values.
*
The pattern of a valid placeholder is {@literal %_%}.
@@ -113,11 +93,25 @@ public final class PlaceholderAPI {
* @return String containing all translated placeholders
*/
@NotNull
- public static List setPlaceholders(final Player player,
+ public static List setPlaceholders(final PlayerRef player,
@NotNull final List text) {
return text.stream().map(line -> setPlaceholders(player, line)).collect(Collectors.toList());
}
+// /**
+// * Translates all placeholders into their corresponding values.
+// *
The pattern of a valid placeholder is {@literal %_%}.
+// *
+// * @param player Player to parse the placeholders against
+// * @param original List of Messages to set the placeholder values in
+// * @return List of Message containing all translated placeholders
+// */
+// @NotNull
+// public static List setPlaceholders(final Player player,
+// @NotNull final List original) {
+// return original.stream().map(msg -> setPlaceholders(player, msg)).collect(Collectors.toList());
+// }
+
// /**
// * Translates all placeholders into their corresponding values.
// *
The pattern of a valid placeholder is {@literal %_%}.
@@ -153,12 +147,18 @@ public final class PlaceholderAPI {
* @return String containing all translated placeholders
*/
@NotNull
- public static String setBracketPlaceholders(final Player player,
+ public static String setBracketPlaceholders(final PlayerRef player,
@NotNull final String text) {
return REPLACER_BRACKET.apply(text, player,
PlaceholderAPIPlugin.instance().localExpansionManager()::getExpansion);
}
+ @NotNull
+ public static Message setBracketPlaceholders(final PlayerRef player,
+ @NotNull final Message original) {
+ return MessageReplacer.replace(original, str -> setBracketPlaceholders(player, str));
+ }
+
/**
* Translates all placeholders into their corresponding values.
*
The pattern of a valid placeholder is {@literal {_}}.
@@ -168,7 +168,7 @@ public final class PlaceholderAPI {
* @return String containing all translated placeholders
*/
@NotNull
- public static List<@NotNull String> setBracketPlaceholders(final Player player,
+ public static List<@NotNull String> setBracketPlaceholders(final PlayerRef player,
@NotNull final List<@NotNull String> text) {
return text.stream().map(line -> setBracketPlaceholders(player, line))
.collect(Collectors.toList());
diff --git a/src/main/java/at/helpch/placeholderapi/PlaceholderHook.java b/src/main/java/at/helpch/placeholderapi/PlaceholderHook.java
index 3776a7a..292249c 100644
--- a/src/main/java/at/helpch/placeholderapi/PlaceholderHook.java
+++ b/src/main/java/at/helpch/placeholderapi/PlaceholderHook.java
@@ -25,19 +25,7 @@ import com.hypixel.hytale.server.core.universe.PlayerRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public abstract class PlaceholderHook {
+public interface PlaceholderHook {
@Nullable
- public String onRequest(final Player player, @NotNull final String params) {
-// Player player2;
-// if (player != null && player.isOnline()) {
-// return onPlaceholderRequest(player.getPlayer(), params);
-// }
-
- return onPlaceholderRequest(player, params);
- }
-
- @Nullable
- public String onPlaceholderRequest(final Player player, @NotNull final String params) {
- return null;
- }
+ String onPlaceholderRequest(final PlayerRef player, @NotNull final String params);
}
diff --git a/src/main/java/at/helpch/placeholderapi/expansion/PlaceholderExpansion.java b/src/main/java/at/helpch/placeholderapi/expansion/PlaceholderExpansion.java
index 4566bbf..0975d06 100644
--- a/src/main/java/at/helpch/placeholderapi/expansion/PlaceholderExpansion.java
+++ b/src/main/java/at/helpch/placeholderapi/expansion/PlaceholderExpansion.java
@@ -20,17 +20,16 @@
package at.helpch.placeholderapi.expansion;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.logging.Level;
+import java.util.regex.Pattern;
import at.helpch.placeholderapi.PlaceholderAPIPlugin;
import at.helpch.placeholderapi.PlaceholderHook;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.plugin.PluginBase;
import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +39,8 @@ import org.jetbrains.annotations.Nullable;
* class extending this one is located under the {@code PlaceholderAPI/expansions}
* directory or when the {@link #register()} method is called by said class.
*/
-public abstract class PlaceholderExpansion extends PlaceholderHook {
+public abstract class PlaceholderExpansion implements PlaceholderHook {
+ private static final Pattern PATH_DELIMITER = Pattern.compile(".");
/**
* The type is {@link Type#INTERNAL} by default.
@@ -224,113 +224,157 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
// return section == null ? null : section.getConfigurationSection(path);
// }
-// /**
-// * Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the provided Default Object, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the Object from. This is relative to the default section
-// * @param def The default Object to return when the ConfigurationSection returns null
-// * @return Object from the provided path or the default one provided
-// */
-// @Nullable
-// @Contract("_, !null -> !null")
-// public final Object get(@NotNull final String path, final Object def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.get(path, def);
-// }
+ /**
+ * Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the provided Default Object, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the Object from. This is relative to the default section
+ * @param def The default Object to return when the ConfigurationSection returns null
+ * @return Object from the provided path or the default one provided
+ */
+ @Nullable
+ @Contract("_, !null -> !null")
+ public final Object get(@NotNull final String path, final Object def) {
+ return get(new ArrayDeque<>(Arrays.asList(PATH_DELIMITER.split(path))), def, getExpansionConfig());
+ }
-// /**
-// * Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the provided Default int, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the int from. This is relative to the default section
-// * @param def The default int to return when the ConfigurationSection returns null
-// * @return int from the provided path or the default one provided
-// */
-// public final int getInt(@NotNull final String path, final int def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.getInt(path, def);
-// }
-//
-// /**
-// * Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the provided Default long, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the long from. This is relative to the default section
-// * @param def The default long to return when the ConfigurationSection returns null
-// * @return long from the provided path or the default one provided
-// */
-// public final long getLong(@NotNull final String path, final long def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.getLong(path, def);
-// }
-//
-// /**
-// * Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the provided Default double, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the double from. This is relative to the default section
-// * @param def The default double to return when the ConfigurationSection returns null
-// * @return double from the provided path or the default one provided
-// */
-// public final double getDouble(@NotNull final String path, final double def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.getDouble(path, def);
-// }
-//
-// /**
-// * Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the provided Default String, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the String from. This is relative to the default section
-// * @param def The default String to return when the ConfigurationSection returns null. Can be null
-// * @return String from the provided path or the default one provided
-// */
-// @Nullable
-// @Contract("_, !null -> !null")
-// public final String getString(@NotNull final String path, @Nullable final String def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.getString(path, def);
-// }
-//
-// /**
-// * Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or an empty List, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the String list from. This is relative to the default section
-// * @return String list from the provided path or an empty list
-// */
-// @NotNull
-// public final List getStringList(@NotNull final String path) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? Collections.emptyList() : section.getStringList(path);
-// }
-//
-// /**
-// * Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
-// * by the expansion or the default boolean, when the default ConfigurationSection is null
-// *
-// * @param path The path to get the boolean from. This is relative to the default section
-// * @param def The default boolean to return when the ConfigurationSection is null
-// * @return boolean from the provided path or the default one provided
-// */
-// public final boolean getBoolean(@NotNull final String path, final boolean def) {
-// final ConfigurationSection section = getConfigSection();
-// return section == null ? def : section.getBoolean(path, def);
-// }
-//
-// /**
-// * Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
-// * or not. This will return {@code false} when either the default section is null, or doesn't
-// * contain the provided path
-// *
-// * @param path The path to check
-// * @return true when the default ConfigurationSection is not null and contains the path, false otherwise
-// */
-// public final boolean configurationContains(@NotNull final String path) {
-// final ConfigurationSection section = getConfigSection();
-// return section != null && section.contains(path);
-// }
+ private Object get(@NotNull final Queue path, final Object def, @NotNull final Map map) {
+ if (path.size() == 1) {
+ return map.getOrDefault(path.poll(), def);
+ }
+
+ Object obj = map.get(path.poll());
+
+ if (!(obj instanceof Map, ?>)) {
+ return def;
+ }
+
+ return get(path, def, (Map) obj);
+ }
+
+ /**
+ * Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the provided Default int, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the int from. This is relative to the default section
+ * @param def The default int to return when the ConfigurationSection returns null
+ * @return int from the provided path or the default one provided
+ */
+ public final int getInt(@NotNull final String path, final int def) {
+ final Object obj = get(path, def);
+
+ if (!(obj instanceof Integer)) {
+ return def;
+ }
+
+ return (Integer) obj;
+ }
+
+ /**
+ * Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the provided Default long, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the long from. This is relative to the default section
+ * @param def The default long to return when the ConfigurationSection returns null
+ * @return long from the provided path or the default one provided
+ */
+ public final long getLong(@NotNull final String path, final long def) {
+ final Object obj = get(path, def);
+
+ if (!(obj instanceof Long) ) {
+ return def;
+ }
+
+ return (Long) obj;
+ }
+
+ /**
+ * Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the provided Default double, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the double from. This is relative to the default section
+ * @param def The default double to return when the ConfigurationSection returns null
+ * @return double from the provided path or the default one provided
+ */
+ public final double getDouble(@NotNull final String path, final double def) {
+ final Object obj = get(path, def);
+
+ if (!(obj instanceof Double) ) {
+ return def;
+ }
+
+ return (Double) obj;
+ }
+
+ /**
+ * Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the provided Default String, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the String from. This is relative to the default section
+ * @param def The default String to return when the ConfigurationSection returns null. Can be null
+ * @return String from the provided path or the default one provided
+ */
+ @Nullable
+ @Contract("_, !null -> !null")
+ public final String getString(@NotNull final String path, @Nullable final String def) {
+ final Object obj = get(path, def);
+
+ if (!(obj instanceof String)) {
+ return def;
+ }
+
+ return (String) obj;
+ }
+
+ /**
+ * Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or an empty List, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the String list from. This is relative to the default section
+ * @return String list from the provided path or an empty list
+ */
+ @NotNull
+ public final List getStringList(@NotNull final String path) {
+ final Object obj = get(path, new ArrayList<>());
+
+ if (!(obj instanceof List>)) {
+ return new ArrayList<>();
+ }
+
+ return (List) obj;
+ }
+
+ /**
+ * Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
+ * by the expansion or the default boolean, when the default ConfigurationSection is null
+ *
+ * @param path The path to get the boolean from. This is relative to the default section
+ * @param def The default boolean to return when the ConfigurationSection is null
+ * @return boolean from the provided path or the default one provided
+ */
+ public final boolean getBoolean(@NotNull final String path, final boolean def) {
+ final Object obj = get(path, def);
+
+ if (!(obj instanceof Boolean)) {
+ return def;
+ }
+
+ return (Boolean) obj;
+ }
+
+ /**
+ * Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
+ * or not. This will return {@code false} when either the default section is null, or doesn't
+ * contain the provided path
+ *
+ * @param path The path to check
+ * @return true when the default ConfigurationSection is not null and contains the path, false otherwise
+ */
+ public final boolean configurationContains(@NotNull final String path) {
+ final Object obj = get(path, null);
+
+ return obj == null;
+ }
/**
* Logs the provided message with the provided Level in the console.
diff --git a/src/main/java/at/helpch/placeholderapi/replacer/CharsReplacer.java b/src/main/java/at/helpch/placeholderapi/replacer/CharsReplacer.java
index 1c8ef06..d0bfed8 100644
--- a/src/main/java/at/helpch/placeholderapi/replacer/CharsReplacer.java
+++ b/src/main/java/at/helpch/placeholderapi/replacer/CharsReplacer.java
@@ -25,6 +25,7 @@ import java.util.function.Function;
import at.helpch.placeholderapi.expansion.PlaceholderExpansion;
import com.hypixel.hytale.server.core.entity.entities.Player;
+import com.hypixel.hytale.server.core.universe.PlayerRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +41,7 @@ public final class CharsReplacer implements Replacer {
@NotNull
@Override
- public String apply(@NotNull final String text, @Nullable final Player player,
+ public String apply(@NotNull final String text, @Nullable final PlayerRef player,
@NotNull final Function lookup) {
final char[] chars = text.toCharArray();
final StringBuilder builder = new StringBuilder(text.length());
diff --git a/src/main/java/at/helpch/placeholderapi/replacer/MessageReplacer.java b/src/main/java/at/helpch/placeholderapi/replacer/MessageReplacer.java
new file mode 100644
index 0000000..83f32a6
--- /dev/null
+++ b/src/main/java/at/helpch/placeholderapi/replacer/MessageReplacer.java
@@ -0,0 +1,50 @@
+package at.helpch.placeholderapi.replacer;
+
+import at.helpch.placeholderapi.PlaceholderAPI;
+import com.hypixel.hytale.server.core.Message;
+import com.hypixel.hytale.server.core.entity.entities.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+public final class MessageReplacer {
+ @NotNull
+ public static Message replace(@NotNull final Message original, @NotNull final Function setPlaceholders) {
+ if (original.getFormattedMessage().rawText == null) {
+ return original;
+ }
+
+ String replaced = setPlaceholders.apply(original.getFormattedMessage().rawText);
+ String link = original.getFormattedMessage().link == null ? null : setPlaceholders.apply(original.getFormattedMessage().link);
+
+ List newChildren = original.getChildren().stream()
+ .filter(Objects::nonNull)
+ .map(child -> replace(child, setPlaceholders))
+ .toList();
+
+ Message message = Message.raw(replaced);
+
+ if (original.getColor() != null) {
+ message = message.color(original.getColor());
+ }
+
+ if (link != null) {
+ message = message.link(link);
+ }
+
+ int bold = original.getFormattedMessage().bold.getValue();
+ if (bold != 0) {
+ message = message.bold(bold != 1);
+ }
+
+ int italic = original.getFormattedMessage().italic.getValue();
+ if (italic != 0) {
+ message = message.italic(italic != 1);
+ }
+
+ return message.insertAll(newChildren);
+ }
+}
diff --git a/src/main/java/at/helpch/placeholderapi/replacer/Replacer.java b/src/main/java/at/helpch/placeholderapi/replacer/Replacer.java
index f1bbeb8..9f455a5 100644
--- a/src/main/java/at/helpch/placeholderapi/replacer/Replacer.java
+++ b/src/main/java/at/helpch/placeholderapi/replacer/Replacer.java
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
public interface Replacer {
@NotNull
- String apply(@NotNull final String text, @Nullable final Player player,
+ String apply(@NotNull final String text, @Nullable final PlayerRef player,
@NotNull final Function lookup);