aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkMVdWPlaceholders.java3
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderApi.java3
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java123
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/SparkPlaceholder.java191
-rw-r--r--spark-fabric/build.gradle2
-rw-r--r--spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java183
-rw-r--r--spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java6
7 files changed, 232 insertions, 279 deletions
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkMVdWPlaceholders.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkMVdWPlaceholders.java
index 078d027..7fa6e02 100644
--- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkMVdWPlaceholders.java
+++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkMVdWPlaceholders.java
@@ -22,6 +22,7 @@ package me.lucko.spark.bukkit.placeholder;
import me.lucko.spark.bukkit.BukkitSparkPlugin;
import me.lucko.spark.common.SparkPlatform;
+import me.lucko.spark.common.util.SparkPlaceholder;
import be.maximvdw.placeholderapi.PlaceholderAPI;
import be.maximvdw.placeholderapi.PlaceholderReplaceEvent;
@@ -43,6 +44,6 @@ public class SparkMVdWPlaceholders implements PlaceholderReplacer {
}
String identifier = placeholder.substring("spark_".length());
- return SparkPlaceholderProvider.respond(this.platform, identifier);
+ return SparkPlaceholder.resolveFormattingCode(this.platform, identifier);
}
}
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderApi.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderApi.java
index 69dca72..b3919dd 100644
--- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderApi.java
+++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderApi.java
@@ -23,6 +23,7 @@ package me.lucko.spark.bukkit.placeholder;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.lucko.spark.bukkit.BukkitSparkPlugin;
import me.lucko.spark.common.SparkPlatform;
+import me.lucko.spark.common.util.SparkPlaceholder;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
@@ -44,7 +45,7 @@ public class SparkPlaceholderApi extends PlaceholderExpansion {
@Override
public String onRequest(OfflinePlayer p, String params) {
- return SparkPlaceholderProvider.respond(this.platform, params);
+ return SparkPlaceholder.resolveFormattingCode(this.platform, params);
}
@Override
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java
deleted file mode 100644
index 5b57857..0000000
--- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/placeholder/SparkPlaceholderProvider.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * This file is part of spark.
- *
- * Copyright (c) lucko (Luck) <luck@lucko.me>
- * Copyright (c) contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package me.lucko.spark.bukkit.placeholder;
-
-import me.lucko.spark.common.SparkPlatform;
-import me.lucko.spark.common.monitor.cpu.CpuMonitor;
-import me.lucko.spark.common.monitor.tick.TickStatistics;
-import me.lucko.spark.common.util.StatisticFormatter;
-
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.TextComponent;
-import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
-
-enum SparkPlaceholderProvider {
- ;
-
- public static TextComponent respondComponent(SparkPlatform platform, String placeholder) {
- if (placeholder.startsWith("tps")) {
- TickStatistics tickStatistics = platform.getTickStatistics();
- if (tickStatistics == null) {
- return null;
- }
-
- switch (placeholder) {
- case "tps":
- return Component.text()
- .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps15Min()))
- .build();
- case "tps_5s":
- return StatisticFormatter.formatTps(tickStatistics.tps5Sec());
- case "tps_10s":
- return StatisticFormatter.formatTps(tickStatistics.tps10Sec());
- case "tps_1m":
- return StatisticFormatter.formatTps(tickStatistics.tps1Min());
- case "tps_5m":
- return StatisticFormatter.formatTps(tickStatistics.tps5Min());
- case "tps_15m":
- return StatisticFormatter.formatTps(tickStatistics.tps15Min());
- }
- }
-
- if (placeholder.startsWith("tickduration")) {
- TickStatistics tickStatistics = platform.getTickStatistics();
- if (tickStatistics == null || !tickStatistics.isDurationSupported()) {
- return null;
- }
-
- switch (placeholder) {
- case "tickduration":
- return Component.text()
- .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; "))
- .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min()))
- .build();
- case "tickduration_10s":
- return StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec());
- case "tickduration_1m":
- return StatisticFormatter.formatTickDurations(tickStatistics.duration1Min());
- }
- }
-
- if (placeholder.startsWith("cpu")) {
- switch (placeholder) {
- case "cpu_system":
- return Component.text()
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg()))
- .build();
- case "cpu_system_10s":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg());
- case "cpu_system_1m":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg());
- case "cpu_system_15m":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg());
- case "cpu_process":
- return Component.text()
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg()))
- .build();
- case "cpu_process_10s":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg());
- case "cpu_process_1m":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg());
- case "cpu_process_15m":
- return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg());
- }
- }
-
- return null;
- }
-
- public static String respond(SparkPlatform platform, String placeholder) {
- TextComponent result = respondComponent(platform, placeholder);
- if (result == null) {
- return null;
- }
- return LegacyComponentSerializer.legacySection().serialize(result);
- }
-
-}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/SparkPlaceholder.java b/spark-common/src/main/java/me/lucko/spark/common/util/SparkPlaceholder.java
new file mode 100644
index 0000000..be5bbc2
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/SparkPlaceholder.java
@@ -0,0 +1,191 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common.util;
+
+import me.lucko.spark.common.SparkPlatform;
+import me.lucko.spark.common.monitor.cpu.CpuMonitor;
+import me.lucko.spark.common.monitor.tick.TickStatistics;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+
+import java.util.Locale;
+import java.util.function.BiFunction;
+
+public enum SparkPlaceholder {
+
+ TPS((platform, arg) -> {
+ TickStatistics tickStatistics = platform.getTickStatistics();
+ if (tickStatistics == null) {
+ return null;
+ }
+
+ if (arg == null) {
+ return Component.text()
+ .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(Component.text(", "))
+ .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(Component.text(", "))
+ .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(Component.text(", "))
+ .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(Component.text(", "))
+ .append(StatisticFormatter.formatTps(tickStatistics.tps15Min()))
+ .build();
+ }
+
+ switch (arg) {
+ case "5s":
+ return StatisticFormatter.formatTps(tickStatistics.tps5Sec());
+ case "10s":
+ return StatisticFormatter.formatTps(tickStatistics.tps10Sec());
+ case "1m":
+ return StatisticFormatter.formatTps(tickStatistics.tps1Min());
+ case "5m":
+ return StatisticFormatter.formatTps(tickStatistics.tps5Min());
+ case "15m":
+ return StatisticFormatter.formatTps(tickStatistics.tps15Min());
+ }
+
+ return null;
+ }),
+
+ TICKDURATION((platform, arg) -> {
+ TickStatistics tickStatistics = platform.getTickStatistics();
+ if (tickStatistics == null || !tickStatistics.isDurationSupported()) {
+ return null;
+ }
+
+ if (arg == null) {
+ return Component.text()
+ .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; "))
+ .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min()))
+ .build();
+ }
+
+ switch (arg) {
+ case "10s":
+ return StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec());
+ case "1m":
+ return StatisticFormatter.formatTickDurations(tickStatistics.duration1Min());
+ }
+
+ return null;
+ }),
+
+ CPU_SYSTEM((platform, arg) -> {
+ if (arg == null) {
+ return Component.text()
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", "))
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", "))
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg()))
+ .build();
+ }
+
+ switch (arg) {
+ case "10s":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg());
+ case "1m":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg());
+ case "15m":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg());
+ }
+
+ return null;
+ }),
+
+ CPU_PROCESS((platform, arg) -> {
+ if (arg == null) {
+ return Component.text()
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", "))
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", "))
+ .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg()))
+ .build();
+ }
+
+ switch (arg) {
+ case "10s":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg());
+ case "1m":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg());
+ case "15m":
+ return StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg());
+ }
+
+ return null;
+ });
+
+ private final String name;
+ private final BiFunction<SparkPlatform, String, TextComponent> function;
+
+ SparkPlaceholder(BiFunction<SparkPlatform, String, TextComponent> function) {
+ this.name = name().toLowerCase(Locale.ROOT);
+ this.function = function;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public TextComponent resolve(SparkPlatform platform, String arg) {
+ return this.function.apply(platform, arg);
+ }
+
+ public static TextComponent resolveComponent(SparkPlatform platform, String placeholder) {
+ String[] parts = placeholder.split("_");
+
+ if (parts.length == 0) {
+ return null;
+ }
+
+ String label = parts[0];
+
+ if (label.equals("tps")) {
+ String arg = parts.length < 2 ? null : parts[1];
+ return TPS.resolve(platform, arg);
+ }
+
+ if (label.equals("tickduration")) {
+ String arg = parts.length < 2 ? null : parts[1];
+ return TICKDURATION.resolve(platform, arg);
+ }
+
+ if (label.equals("cpu") && parts.length >= 2) {
+ String type = parts[1];
+ String arg = parts.length < 3 ? null : parts[2];
+
+ if (type.equals("system")) {
+ return CPU_SYSTEM.resolve(platform, arg);
+ }
+ if (type.equals("process")) {
+ return CPU_PROCESS.resolve(platform, arg);
+ }
+ }
+
+ return null;
+ }
+
+ public static String resolveFormattingCode(SparkPlatform platform, String placeholder) {
+ TextComponent result = resolveComponent(platform, placeholder);
+ if (result == null) {
+ return null;
+ }
+ return LegacyComponentSerializer.legacySection().serialize(result);
+ }
+
+}
diff --git a/spark-fabric/build.gradle b/spark-fabric/build.gradle
index 9da8e01..31008bb 100644
--- a/spark-fabric/build.gradle
+++ b/spark-fabric/build.gradle
@@ -45,7 +45,7 @@ dependencies {
include(modImplementation('me.lucko:fabric-permissions-api:0.1-SNAPSHOT'))
- modImplementation('eu.pb4:placeholder-api:1.1.1+1.17.1')
+ modImplementation('eu.pb4:placeholder-api:2.0.0-beta.4+1.19')
shade project(':spark-common')
}
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java
index dc2e7d9..69303e3 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/placeholder/SparkFabricPlaceholderApi.java
@@ -20,169 +20,48 @@
package me.lucko.spark.fabric.placeholder;
-import eu.pb4.placeholders.PlaceholderAPI;
-import eu.pb4.placeholders.PlaceholderResult;
+import eu.pb4.placeholders.api.PlaceholderContext;
+import eu.pb4.placeholders.api.PlaceholderHandler;
+import eu.pb4.placeholders.api.PlaceholderResult;
+import eu.pb4.placeholders.api.Placeholders;
import me.lucko.spark.common.SparkPlatform;
-import me.lucko.spark.common.monitor.cpu.CpuMonitor;
-import me.lucko.spark.common.monitor.tick.TickStatistics;
-import me.lucko.spark.common.util.RollingAverage;
-import me.lucko.spark.common.util.StatisticFormatter;
+import me.lucko.spark.common.util.SparkPlaceholder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
-public class SparkFabricPlaceholderApi {
- private final SparkPlatform platform;
+import org.jetbrains.annotations.Nullable;
- public SparkFabricPlaceholderApi(SparkPlatform platform) {
- this.platform = platform;
+public enum SparkFabricPlaceholderApi {
+ ;
- PlaceholderAPI.register(
- new Identifier("spark", "tps"),
- context -> {
- TickStatistics tickStatistics = platform.getTickStatistics();
- if (tickStatistics == null) {
- return PlaceholderResult.invalid();
- }
-
- if (context.hasArgument()) {
- Double tps = switch (context.getArgument()) {
- case "5s":
- yield tickStatistics.tps5Sec();
- case "10s":
- yield tickStatistics.tps10Sec();
- case "1m":
- yield tickStatistics.tps1Min();
- case "5m":
- yield tickStatistics.tps5Min();
- case "15m":
- yield tickStatistics.tps15Min();
- default:
- yield null;
- };
-
- if (tps == null) {
- return PlaceholderResult.invalid("Invalid argument");
- } else {
- return PlaceholderResult.value(toText(StatisticFormatter.formatTps(tps)));
- }
- } else {
- return PlaceholderResult.value(toText(
- Component.text()
- .append(StatisticFormatter.formatTps(tickStatistics.tps5Sec())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps10Sec())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps1Min())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps5Min())).append(Component.text(", "))
- .append(StatisticFormatter.formatTps(tickStatistics.tps15Min()))
- .build()
- ));
- }
- }
- );
-
- PlaceholderAPI.register(
- new Identifier("spark", "tickduration"),
- context -> {
- TickStatistics tickStatistics = platform.getTickStatistics();
- if (tickStatistics == null || !tickStatistics.isDurationSupported()) {
- return PlaceholderResult.invalid();
- }
-
- if (context.hasArgument()) {
- RollingAverage duration = switch (context.getArgument()) {
- case "10s":
- yield tickStatistics.duration10Sec();
- case "1m":
- yield tickStatistics.duration1Min();
- default:
- yield null;
- };
-
- if (duration == null) {
- return PlaceholderResult.invalid("Invalid argument");
- } else {
- return PlaceholderResult.value(toText(StatisticFormatter.formatTickDurations(duration)));
- }
- } else {
- return PlaceholderResult.value(toText(
- Component.text()
- .append(StatisticFormatter.formatTickDurations(tickStatistics.duration10Sec())).append(Component.text("; "))
- .append(StatisticFormatter.formatTickDurations(tickStatistics.duration1Min()))
- .build()
- ));
- }
- }
- );
-
- PlaceholderAPI.register(
- new Identifier("spark", "cpu_system"),
- context -> {
- if (context.hasArgument()) {
- Double usage = switch (context.getArgument()) {
- case "10s":
- yield CpuMonitor.systemLoad10SecAvg();
- case "1m":
- yield CpuMonitor.systemLoad1MinAvg();
- case "15m":
- yield CpuMonitor.systemLoad15MinAvg();
- default:
- yield null;
- };
-
- if (usage == null) {
- return PlaceholderResult.invalid("Invalid argument");
- } else {
- return PlaceholderResult.value(toText(StatisticFormatter.formatCpuUsage(usage)));
- }
- } else {
- return PlaceholderResult.value(toText(
- Component.text()
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad10SecAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad1MinAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.systemLoad15MinAvg()))
- .build()
- ));
- }
- }
- );
-
- PlaceholderAPI.register(
- new Identifier("spark", "cpu_process"),
- context -> {
- if (context.hasArgument()) {
- Double usage = switch (context.getArgument()) {
- case "10s":
- yield CpuMonitor.processLoad10SecAvg();
- case "1m":
- yield CpuMonitor.processLoad1MinAvg();
- case "15m":
- yield CpuMonitor.processLoad15MinAvg();
- default:
- yield null;
- };
-
- if (usage == null) {
- return PlaceholderResult.invalid("Invalid argument");
- } else {
- return PlaceholderResult.value(toText(StatisticFormatter.formatCpuUsage(usage)));
- }
- } else {
- return PlaceholderResult.value(toText(
- Component.text()
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad10SecAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad1MinAvg())).append(Component.text(", "))
- .append(StatisticFormatter.formatCpuUsage(CpuMonitor.processLoad15MinAvg()))
- .build()
- ));
- }
- }
- );
+ public static void register(SparkPlatform platform) {
+ for (SparkPlaceholder placeholder : SparkPlaceholder.values()) {
+ Placeholders.register(
+ new Identifier("spark", placeholder.getName()),
+ new Handler(platform, placeholder)
+ );
+ }
}
- private Text toText(Component component) {
- return Text.Serializer.fromJson(GsonComponentSerializer.gson().serialize(component));
+ private record Handler(SparkPlatform platform, SparkPlaceholder placeholder) implements PlaceholderHandler {
+ @Override
+ public PlaceholderResult onPlaceholderRequest(PlaceholderContext context, @Nullable String argument) {
+ return toResult(this.placeholder.resolve(this.platform, argument));
+ }
+
+ private static PlaceholderResult toResult(Component component) {
+ return component == null
+ ? PlaceholderResult.invalid()
+ : PlaceholderResult.value(toText(component));
+ }
+
+ private static Text toText(Component component) {
+ return Text.Serializer.fromJson(GsonComponentSerializer.gson().serialize(component));
+ }
}
+
}
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
index 428ac4c..3d1a0e7 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
@@ -74,7 +74,11 @@ public class FabricServerSparkPlugin extends FabricSparkPlugin implements Comman
// placeholders
if (FabricLoader.getInstance().isModLoaded("placeholder-api")) {
- new SparkFabricPlaceholderApi(this.platform);
+ try {
+ SparkFabricPlaceholderApi.register(this.platform);
+ } catch (LinkageError e) {
+ // ignore
+ }
}
}