Working UltimateShopPriceProvider + Testing

Removing import, adding reflect

Took 13 minutes
This commit is contained in:
Molzonas 2025-08-26 14:58:59 +02:00
parent 1f4176eec4
commit 36d13fb199
7 changed files with 115 additions and 53 deletions

View File

@ -1,5 +1,6 @@
stages: stages:
- test - test
- build
- release - release
image: maven:3.9.8-eclipse-temurin-21 image: maven:3.9.8-eclipse-temurin-21
@ -12,7 +13,6 @@ cache:
paths: paths:
- .m2/repository - .m2/repository
# MVN TEST + JUNIT REPORT
test: test:
stage: test stage: test
script: script:
@ -29,10 +29,8 @@ test:
rules: rules:
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_TAG - if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_TAG
# COMPILATION + RELEASE GENERATION build_tag:
release: stage: build
stage: release
needs: ["test"]
script: script:
- mvn -B -ntp -DskipTests package - mvn -B -ntp -DskipTests package
- JAR=$(ls target/*-with-dependencies.jar 2>/dev/null || ls target/*.jar | head -n1) - JAR=$(ls target/*-with-dependencies.jar 2>/dev/null || ls target/*.jar | head -n1)
@ -40,15 +38,20 @@ release:
artifacts: artifacts:
paths: paths:
- target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar - target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar
release: expire_in: 1 year
name: "Release ${CI_COMMIT_TAG}" rules:
tag_name: "${CI_COMMIT_TAG}" - if: $CI_COMMIT_TAG
description: |
New release : ${CI_COMMIT_TAG}. release_tag:
Commit : ${CI_COMMIT_SHA} stage: release
assets: needs: ["build_tag"]
links: image: registry.gitlab.com/gitlab-org/release-cli:latest
- name: "${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar" script:
url: "${CI_JOB_URL}/artifacts/raw/target/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.jar" - >
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: rules:
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG

View File

@ -1,25 +1,16 @@
# Painful Lost # Painful Loss
Le plugin Minecraft fait pour montrer le regret de l'équipement perdu. 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 * Indique dans le chat le prix de l'équipement complet perdu à la mort
* Affiche l'élément le plus cher perdu * Affiche l'élément le plus cher perdu
* Utilise les prix du fichier worth.yml de Essentials (fallback) ou les prix de UltimateShop (recommandé) * 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. Suite du README à venir.
## Développement - Mise en place ## Développement - Mise en place
* Clonez Painful Loss * 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
<dependency>
<groupId>cn.superiormc</groupId>
<artifactId>ultimateshop</artifactId>
<version>[version]</version>
<scope>provided</scope>
</dependency>
```
* Mettez à jour les dépendances Maven * Mettez à jour les dépendances Maven
* Utilisez `mvn clean` et `mvn test` pour nettoyer le projet et vérifier la santé du code * 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 * Exécutez en faisant un `mvn package` et en mettant le plugin dans un serveur de test Spigot ou équivalent

View File

@ -90,12 +90,6 @@
<version>2.21.2</version> <version>2.21.2</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>cn.superiormc</groupId>
<artifactId>ultimateshop</artifactId>
<version>3.10.2</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -1,6 +1,7 @@
package fr.molzonas.painfulloss; package fr.molzonas.painfulloss;
import fr.molzonas.painfulloss.commands.PainfulLossCommand; import fr.molzonas.painfulloss.commands.PainfulLossCommand;
import fr.molzonas.painfulloss.provider.UltimateShopPriceProvider;
import fr.molzonas.painfulloss.utils.PropertiesEnum; import fr.molzonas.painfulloss.utils.PropertiesEnum;
import fr.molzonas.painfulloss.listeners.DeathListener; import fr.molzonas.painfulloss.listeners.DeathListener;
import fr.molzonas.painfulloss.provider.CountPriceProvider; import fr.molzonas.painfulloss.provider.CountPriceProvider;
@ -72,7 +73,13 @@ public final class PainfulLoss extends JavaPlugin {
// Ultimate Shop // Ultimate Shop
Plugin ultimateShop = getServer().getPluginManager().getPlugin("UltimateShop"); Plugin ultimateShop = getServer().getPluginManager().getPlugin("UltimateShop");
if (ultimateShop != null && ultimateShop.isEnabled()) { 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 // Essentials

View File

@ -16,4 +16,5 @@ public interface PriceProvider {
} }
default boolean isReady() { return true; } default boolean isReady() { return true; }
default boolean isCountBased() { return false; } default boolean isCountBased() { return false; }
default void reload() { }
} }

View File

@ -1,43 +1,108 @@
package fr.molzonas.painfulloss.provider; package fr.molzonas.painfulloss.provider;
import cn.superiormc.ultimateshop.api.ShopHelper; import fr.molzonas.painfulloss.PainfulLoss;
import cn.superiormc.ultimateshop.objects.items.AbstractSingleThing;
import cn.superiormc.ultimateshop.objects.items.GiveResult;
import fr.molzonas.painfulloss.utils.PropertiesEnum; import fr.molzonas.painfulloss.utils.PropertiesEnum;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Level;
public class UltimateShopPriceProvider implements PriceProvider { 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 @Override
public String getName() { public String getName() {
return "UltimateShop"; return "UltimateShop";
} }
@Override
public boolean isReady() {
return this.ready;
}
@Override @Override
public Optional<Double> getPrice(ItemStack stack, @Nullable Player player) { public Optional<Double> getPrice(ItemStack stack, @Nullable Player player) {
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() <= 0) return Optional.empty(); try {
double total = 0d; return Optional.of(reflect.priceFor(stack, player, economyProvider));
GiveResult gr = ShopHelper.getSellPrices(new ItemStack[]{stack}, player, stack.getAmount()); } catch (Exception e) {
if (gr == null) return Optional.empty(); return Optional.empty();
Map<AbstractSingleThing, BigDecimal> map = gr.getResultMap(); }
if (map == null || map.isEmpty()) return Optional.empty(); }
for (Map.Entry<AbstractSingleThing, BigDecimal> entry : map.entrySet()) {
AbstractSingleThing key = entry.getKey(); @Override
BigDecimal value = entry.getValue(); public void reload() {
ConfigurationSection section = key.getSingleSection(); economyProvider = PropertiesEnum.ECONOMY_PROVIDER.getString();
String econ = section.getString("economy-plugin", ""); }
if (econ.equalsIgnoreCase(PropertiesEnum.PRICE_PROVIDER.getString())) {
total += value.doubleValue(); 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<Object, BigDecimal> map = (Map<Object, BigDecimal>) giveResultMap.invoke(result);
if (map == null || map.isEmpty()) return total;
if (getSingleSection == null) {
Object anyKey = map.keySet().iterator().next();
getSingleSection = anyKey.getClass().getMethod("getSingleSection");
Object sec = getSingleSection.invoke(anyKey);
sectionGetString = sec.getClass().getMethod("getString", String.class, String.class);
}
for (Map.Entry<Object, BigDecimal> entry : map.entrySet()) {
Object section = getSingleSection.invoke(entry.getKey());
String economyPlugin = String.valueOf(sectionGetString.invoke(section, "economy-plugin", ""));
if (!economyPlugin.equalsIgnoreCase(economyProvider)) continue;
BigDecimal value = entry.getValue();
if (value != null) total += entry.getValue().doubleValue();
}
return total;
}
} }
} }

View File

@ -2,6 +2,7 @@ name: PainfulLoss
version: '1.0' version: '1.0'
main: fr.molzonas.painfulloss.PainfulLoss main: fr.molzonas.painfulloss.PainfulLoss
api-version: '1.20' api-version: '1.20'
prefix: PainfulLoss
softdepend: [Essentials, UltimateShop] softdepend: [Essentials, UltimateShop]
author: Molzonas author: Molzonas
commands: commands: