diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0d50da0..fac0d11 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,6 @@
stages:
- test
+ - build
- release
image: maven:3.9.8-eclipse-temurin-21
@@ -12,7 +13,6 @@ cache:
paths:
- .m2/repository
-# MVN TEST + JUNIT REPORT
test:
stage: test
script:
@@ -29,10 +29,8 @@ test:
rules:
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_TAG
-# COMPILATION + RELEASE GENERATION
-release:
- stage: release
- needs: ["test"]
+build_tag:
+ stage: build
script:
- mvn -B -ntp -DskipTests package
- JAR=$(ls target/*-with-dependencies.jar 2>/dev/null || ls target/*.jar | head -n1)
@@ -40,15 +38,20 @@ release:
artifacts:
paths:
- target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar
- release:
- name: "Release ${CI_COMMIT_TAG}"
- tag_name: "${CI_COMMIT_TAG}"
- description: |
- New release : ${CI_COMMIT_TAG}.
- Commit : ${CI_COMMIT_SHA}
- assets:
- links:
- - name: "${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar"
- url: "${CI_JOB_URL}/artifacts/raw/target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar"
+ expire_in: 1 year
+ rules:
+ - if: $CI_COMMIT_TAG
+
+release_tag:
+ stage: release
+ needs: ["build_tag"]
+ image: registry.gitlab.com/gitlab-org/release-cli:latest
+ script:
+ - >
+ release-cli create
+ --name "Release ${CI_COMMIT_TAG}"
+ --tag-name "${CI_COMMIT_TAG}"
+ --description "New release : ${CI_COMMIT_TAG} - Commit : ${CI_COMMIT_SHA})."
+ --assets-link "{\"name\":\"${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar\",\"url\":\"${CI_PROJECT_URL}/-/jobs/artifacts/${CI_COMMIT_TAG}/raw/target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar?job=build_tag\"}"
rules:
- if: $CI_COMMIT_TAG
\ No newline at end of file
diff --git a/README.md b/README.md
index d5b28ba..1cf27db 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,16 @@
-# Painful Lost
+# Painful Loss
Le plugin Minecraft fait pour montrer le regret de l'équipement perdu.
* Indique dans le chat le prix de l'équipement complet perdu à la mort
* Affiche l'élément le plus cher perdu
* Utilise les prix du fichier worth.yml de Essentials (fallback) ou les prix de UltimateShop (recommandé)
+**Requiert d'avoir UltimateShop >= 3.10.2 !**
+
Suite du README à venir.
## Développement - Mise en place
* Clonez Painful Loss
-* Téléchargez la dernière version de UltimateShop
-* Ajoutez UltimateShop à votre repository local : `mvn install:install-file -Dfile="[chemin]/UltimateShop.jar" -DgroupId="cn.superiormc" -DartifactId="ultimateshop" -Dversion="[version]" -Dpackaging=jar`
-* Indiquez dans le `pom.xml` la dernière version :
-```xml
-
- cn.superiormc
- ultimateshop
- [version]
- provided
-
-```
* Mettez à jour les dépendances Maven
* Utilisez `mvn clean` et `mvn test` pour nettoyer le projet et vérifier la santé du code
* Exécutez en faisant un `mvn package` et en mettant le plugin dans un serveur de test Spigot ou équivalent
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3df999c..fe8cda1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,12 +90,6 @@
2.21.2
provided
-
- cn.superiormc
- ultimateshop
- 3.10.2
- provided
-
junit
junit
diff --git a/src/main/java/fr/molzonas/painfulloss/PainfulLoss.java b/src/main/java/fr/molzonas/painfulloss/PainfulLoss.java
index c190d6e..412cee5 100644
--- a/src/main/java/fr/molzonas/painfulloss/PainfulLoss.java
+++ b/src/main/java/fr/molzonas/painfulloss/PainfulLoss.java
@@ -1,6 +1,7 @@
package fr.molzonas.painfulloss;
import fr.molzonas.painfulloss.commands.PainfulLossCommand;
+import fr.molzonas.painfulloss.provider.UltimateShopPriceProvider;
import fr.molzonas.painfulloss.utils.PropertiesEnum;
import fr.molzonas.painfulloss.listeners.DeathListener;
import fr.molzonas.painfulloss.provider.CountPriceProvider;
@@ -72,7 +73,13 @@ public final class PainfulLoss extends JavaPlugin {
// Ultimate Shop
Plugin ultimateShop = getServer().getPluginManager().getPlugin("UltimateShop");
if (ultimateShop != null && ultimateShop.isEnabled()) {
- info("UltimateShop detected (but inactive for Painful Loss)");
+ UltimateShopPriceProvider uspp = new UltimateShopPriceProvider(ultimateShop);
+ if (uspp.isReady()) {
+ ultimateShopProvider = Optional.of(uspp);
+ info("UltimateShop detected, prices loaded");
+ } else {
+ info("UltimateShop detected, prices unavailable");
+ }
}
// Essentials
diff --git a/src/main/java/fr/molzonas/painfulloss/provider/PriceProvider.java b/src/main/java/fr/molzonas/painfulloss/provider/PriceProvider.java
index 131a3bd..0c6397e 100644
--- a/src/main/java/fr/molzonas/painfulloss/provider/PriceProvider.java
+++ b/src/main/java/fr/molzonas/painfulloss/provider/PriceProvider.java
@@ -16,4 +16,5 @@ public interface PriceProvider {
}
default boolean isReady() { return true; }
default boolean isCountBased() { return false; }
+ default void reload() { }
}
diff --git a/src/main/java/fr/molzonas/painfulloss/provider/UltimateShopPriceProvider.java b/src/main/java/fr/molzonas/painfulloss/provider/UltimateShopPriceProvider.java
index 8d3ef07..4782f85 100644
--- a/src/main/java/fr/molzonas/painfulloss/provider/UltimateShopPriceProvider.java
+++ b/src/main/java/fr/molzonas/painfulloss/provider/UltimateShopPriceProvider.java
@@ -1,43 +1,108 @@
package fr.molzonas.painfulloss.provider;
-import cn.superiormc.ultimateshop.api.ShopHelper;
-import cn.superiormc.ultimateshop.objects.items.AbstractSingleThing;
-import cn.superiormc.ultimateshop.objects.items.GiveResult;
+import fr.molzonas.painfulloss.PainfulLoss;
import fr.molzonas.painfulloss.utils.PropertiesEnum;
-import org.bukkit.Material;
-import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
+import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Optional;
+import java.util.logging.Level;
public class UltimateShopPriceProvider implements PriceProvider {
+ private final Reflect reflect;
+ private String economyProvider;
+ private boolean ready = true;
+
+ public UltimateShopPriceProvider(Plugin plugin) {
+ reload();
+ this.reflect = Reflect.resolve(plugin);
+
+ if (this.reflect == null) {
+ this.ready = false;
+ PainfulLoss.log(Level.WARNING, "UltimateShop API not found");
+ }
+ }
@Override
public String getName() {
return "UltimateShop";
}
+ @Override
+ public boolean isReady() {
+ return this.ready;
+ }
+
@Override
public Optional getPrice(ItemStack stack, @Nullable Player player) {
- if (stack == null || stack.getType() == Material.AIR || stack.getAmount() <= 0) return Optional.empty();
- double total = 0d;
- GiveResult gr = ShopHelper.getSellPrices(new ItemStack[]{stack}, player, stack.getAmount());
- if (gr == null) return Optional.empty();
- Map map = gr.getResultMap();
- if (map == null || map.isEmpty()) return Optional.empty();
- for (Map.Entry entry : map.entrySet()) {
- AbstractSingleThing key = entry.getKey();
- BigDecimal value = entry.getValue();
- ConfigurationSection section = key.getSingleSection();
- String econ = section.getString("economy-plugin", "");
- if (econ.equalsIgnoreCase(PropertiesEnum.PRICE_PROVIDER.getString())) {
- total += value.doubleValue();
+ try {
+ return Optional.of(reflect.priceFor(stack, player, economyProvider));
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public void reload() {
+ economyProvider = PropertiesEnum.ECONOMY_PROVIDER.getString();
+ }
+
+ static final class Reflect {
+ private static final String SHOPHELPER_CLASSNAME = "cn.superiormc.ultimateshop.api.ShopHelper";
+
+ final Method getSellPrices;
+ final Method giveResultMap;
+ Method getSingleSection;
+ Method sectionGetString;
+
+ private Reflect(Method sellPrices, Method giveResultMap) {
+ this.getSellPrices = sellPrices;
+ this.giveResultMap = giveResultMap;
+ }
+
+ static Reflect resolve(Plugin plugin) {
+ try {
+ ClassLoader cl = plugin.getClass().getClassLoader();
+ Class> c = Class.forName(SHOPHELPER_CLASSNAME, false, cl);
+ Method gp = c.getMethod("getSellPrices", ItemStack[].class, Player.class, int.class);
+ Class> resultClass = gp.getReturnType();
+ Method getMap = resultClass.getMethod("getResultMap");
+ return new Reflect(gp, getMap);
+ } catch (Exception ex) {
+ return null;
}
}
- return total > 0 ? Optional.of(total) : Optional.empty();
+
+ double priceFor(ItemStack item, Player player, String economyProvider) throws Exception {
+ if (item == null || item.getType().isAir() || item.getAmount() <= 0) return 0d;
+ Object result = getSellPrices.invoke(null, new ItemStack[]{item}, player, item.getAmount());
+ double total = 0d;
+ if (result == null) return total;
+
+ Map