diff --git a/pom.xml b/pom.xml
index 26f377a..56855df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,12 +47,18 @@
HikariCP
5.1.0
-
- com.mysql
- mysql-connector-j
- 8.4.0
-
-
+
+ com.mysql
+ mysql-connector-j
+ 8.4.0
+
+
+ me.clip
+ placeholderapi
+ 2.11.5
+ provided
+
+
diff --git a/src/main/java/com/yourorg/servershop/ServerShopPlugin.java b/src/main/java/com/yourorg/servershop/ServerShopPlugin.java
index 5f18fb9..1254244 100644
--- a/src/main/java/com/yourorg/servershop/ServerShopPlugin.java
+++ b/src/main/java/com/yourorg/servershop/ServerShopPlugin.java
@@ -41,6 +41,10 @@ public final class ServerShopPlugin extends JavaPlugin {
this.menus = new MenuManager(this);
Bukkit.getPluginManager().registerEvents(menus, this);
+ if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
+ new com.yourorg.servershop.papi.ShopPlaceholderExpansion(this).register();
+ }
+
int saveEvery = Math.max(1, getConfig().getInt("dynamicPricing.decay.saveEveryMinutes", 5));
Bukkit.getScheduler().runTaskTimerAsynchronously(this, dynamic::tickSaveAll, 20L * 60L * saveEvery, 20L * 60L * saveEvery);
diff --git a/src/main/java/com/yourorg/servershop/papi/ShopPlaceholderExpansion.java b/src/main/java/com/yourorg/servershop/papi/ShopPlaceholderExpansion.java
new file mode 100644
index 0000000..2fc3d5d
--- /dev/null
+++ b/src/main/java/com/yourorg/servershop/papi/ShopPlaceholderExpansion.java
@@ -0,0 +1,59 @@
+package com.yourorg.servershop.papi;
+
+import com.yourorg.servershop.ServerShopPlugin;
+import me.clip.placeholderapi.expansion.PlaceholderExpansion;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+/**
+ * PlaceholderAPI expansion for the shop plugin.
+ */
+public final class ShopPlaceholderExpansion extends PlaceholderExpansion {
+ private final ServerShopPlugin plugin;
+
+ public ShopPlaceholderExpansion(ServerShopPlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override public String getIdentifier() { return "shop"; }
+ @Override public String getAuthor() { return String.join(", ", plugin.getDescription().getAuthors()); }
+ @Override public String getVersion() { return plugin.getDescription().getVersion(); }
+ @Override public boolean persist() { return true; }
+ @Override public boolean canRegister() { return true; }
+
+ @Override
+ public String onPlaceholderRequest(Player player, String params) {
+ if (params == null) return "";
+ params = params.toLowerCase();
+
+ if (params.startsWith("price_")) {
+ String matName = params.substring(6).toUpperCase();
+ Material mat = Material.matchMaterial(matName);
+ if (mat == null) return "";
+ double price = plugin.shop().priceBuy(mat);
+ return price < 0 ? "" : String.format("%.2f", price);
+ }
+
+ if (params.startsWith("sellprice_")) {
+ String matName = params.substring(10).toUpperCase();
+ Material mat = Material.matchMaterial(matName);
+ if (mat == null) return "";
+ double price = plugin.shop().priceSell(mat);
+ return price < 0 ? "" : String.format("%.2f", price);
+ }
+
+ if (params.startsWith("category_multiplier_")) {
+ String cat = params.substring("category_multiplier_".length());
+ double mult = plugin.categorySettings().multiplier(cat);
+ return String.format("%.2f", mult);
+ }
+
+ if (params.startsWith("category_enabled_")) {
+ String cat = params.substring("category_enabled_".length());
+ return String.valueOf(plugin.categorySettings().isEnabled(cat));
+ }
+
+ return null;
+ }
+}
+
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index ff3ab10..f12d638 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -3,6 +3,7 @@ main: com.yourorg.servershop.ServerShopPlugin
version: 1.2.0
api-version: '1.20'
depend: [Vault]
+softdepend: [PlaceholderAPI]
author: yourorg
description: Dynamic server shop with GUIs, MySQL logging, importer, and per-item dynamic pricing.
commands: