Ajoute un expansion PlaceholderAPI (%votenetwork_...%)

Le scoreboard du joueur affichait %current%/%required% en clair car
seule une API Java existait, pas de placeholders texte. Enregistre
automatiquement si PlaceholderAPI est present (softdepend) :
voteparty_current, voteparty_required, voteparty_remaining,
maintenance, pending (rafraichi en arriere-plan, async).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
SarTron-NorthBlue
2026-07-12 14:26:44 +04:00
co-authored by Claude Sonnet 5
parent a76c641b7d
commit 74b2914529
5 changed files with 134 additions and 0 deletions
+10
View File
@@ -36,6 +36,12 @@
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
@@ -47,6 +53,10 @@
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<build>
@@ -6,10 +6,12 @@ import fr.votenetwork.spigot.api.VoteNetworkAPIImpl;
import fr.votenetwork.spigot.command.ClaimCommand;
import fr.votenetwork.spigot.command.VoteAdminCommand;
import fr.votenetwork.spigot.listener.VoteMessageListener;
import fr.votenetwork.spigot.placeholder.VoteNetworkPlaceholders;
import fr.votenetwork.spigot.storage.MySqlPendingVoteStore;
import fr.votenetwork.spigot.storage.PendingVoteStore;
import fr.votenetwork.spigot.storage.YamlPendingVoteStore;
import fr.votenetwork.spigot.voteparty.VoteParty;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
@@ -58,6 +60,11 @@ public class VoteNetworkSpigot extends JavaPlugin {
VoteNetworkAPIHolder.set(api);
getServer().getServicesManager().register(VoteNetworkAPI.class, api, this, ServicePriority.Normal);
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
new VoteNetworkPlaceholders(this, voteConfig, pendingVoteStore, voteParty, maintenanceState).register();
getLogger().info("Placeholders PlaceholderAPI enregistres (%votenetwork_...%).");
}
getLogger().info("VoteNetwork (Spigot) demarre.");
}
@@ -0,0 +1,102 @@
package fr.votenetwork.spigot.placeholder;
import fr.votenetwork.spigot.MaintenanceState;
import fr.votenetwork.spigot.VoteConfig;
import fr.votenetwork.spigot.VoteNetworkSpigot;
import fr.votenetwork.spigot.storage.PendingVoteStore;
import fr.votenetwork.spigot.voteparty.VoteParty;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Placeholders PlaceholderAPI :
* %votenetwork_voteparty_current%
* %votenetwork_voteparty_required%
* %votenetwork_voteparty_remaining%
* %votenetwork_maintenance% -> "true"/"false"
* %votenetwork_pending% -> votes en attente du joueur (rafraichi en arriere-plan)
*
* Utilisables dans n'importe quel plugin de scoreboard/GUI qui supporte PlaceholderAPI
* (%votenetwork_...%, pas %current%/%required% bruts : ces derniers doivent etre configures
* comme placeholders dans le plugin de scoreboard lui-meme).
*/
public class VoteNetworkPlaceholders extends PlaceholderExpansion {
private final VoteNetworkSpigot plugin;
private final VoteConfig config;
private final PendingVoteStore pendingVoteStore;
private final VoteParty voteParty;
private final MaintenanceState maintenanceState;
private final Map<String, Integer> pendingVotesCache = new ConcurrentHashMap<>();
public VoteNetworkPlaceholders(VoteNetworkSpigot plugin, VoteConfig config, PendingVoteStore pendingVoteStore,
VoteParty voteParty, MaintenanceState maintenanceState) {
this.plugin = plugin;
this.config = config;
this.pendingVoteStore = pendingVoteStore;
this.voteParty = voteParty;
this.maintenanceState = maintenanceState;
}
@Override
public @NotNull String getIdentifier() {
return "votenetwork";
}
@Override
public @NotNull String getAuthor() {
return "VoteNetwork";
}
@Override
public @NotNull String getVersion() {
return plugin.getDescription().getVersion();
}
@Override
public boolean persist() {
return true;
}
@Override
public String onRequest(OfflinePlayer player, @NotNull String params) {
switch (params.toLowerCase()) {
case "voteparty_current":
return String.valueOf(voteParty.getCurrentVotes());
case "voteparty_required":
return String.valueOf(config.getVotePartyVotesRequired());
case "voteparty_remaining":
return String.valueOf(Math.max(0, config.getVotePartyVotesRequired() - voteParty.getCurrentVotes()));
case "maintenance":
return String.valueOf(maintenanceState.isStopped());
case "pending":
if (player == null) {
return "0";
}
return String.valueOf(getPendingVotesCached(player));
default:
return null;
}
}
private int getPendingVotesCached(OfflinePlayer player) {
String key = player.getUniqueId().toString();
Integer cached = pendingVotesCache.get(key);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
pendingVoteStore.peek(
player.getUniqueId(),
votes -> pendingVotesCache.put(key, votes),
exception -> { /* on garde la derniere valeur en cache en cas d'erreur */ }
)
);
return cached != null ? cached : 0;
}
}
+1
View File
@@ -4,6 +4,7 @@ version: ${project.version}
api-version: 1.18
author: VoteNetwork
description: Reception des votes reseau (direct ou en attente) avec VoteParty local.
softdepend: [PlaceholderAPI]
commands:
claim: