Code Examples
Practical Java snippets for integrating with the ShyamDuels API on your Spigot/Paper server.
Example 1: Fetching and Modifying ELO Stats
This example demonstrates how to retrieve a player's stats object, view their rating details, add ELO points, and save the data asynchronously:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.stats.PlayerStats;
import org.bukkit.entity.Player;
public void rewardElo(Player player, int eloAmount) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Fetch the player stats cached profile
PlayerStats stats = api.stats().getStats(player);
if (stats == null) return;
int oldElo = stats.getElo();
stats.setElo(oldElo + eloAmount); // Update ELO points
// Save changes back to database pool asynchronously
api.stats().saveStats(stats).thenRun(() -> {
player.sendMessage("§aYour ELO has been updated to: " + stats.getElo());
});
}
Example 2: Listening to Duel Concludes
Listen for when a match ends to log victory parameters or trigger custom server-wide rewards:
javaimport org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import com.shyamstudio.shyamduels.duel.event.DuelEndEvent;
import com.shyamstudio.shyamduels.duel.Duel;
public class EndMatchListener implements Listener {
private final JavaPlugin plugin;
public EndMatchListener(JavaPlugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onDuelEnd(DuelEndEvent event) {
Duel duel = event.getDuel();
String kitName = duel.getKit().getName();
String arenaName = duel.getArena().getName();
plugin.getLogger().info("Duel concluded on arena " + arenaName + " using kit " + kitName);
plugin.getLogger().info("Team 1 Wins: " + duel.getTeam1Wins() + " | Team 2 Wins: " + duel.getTeam2Wins());
}
}
Example 3: Programmatically Inviting Players
Generate a match challenge invite using the API, bypassing user commands:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.kit.Kit;
import org.bukkit.entity.Player;
public void challengePlayer(Player challenger, Player target, String kitName, int roundCount) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Resolve the kit configuration template
Kit kit = api.kits().getKit(kitName);
if (kit == null) {
challenger.sendMessage("§cSpecified kit was not found!");
return;
}
// Dispatch the invite directly through the DuelService
api.duels().sendInvite(challenger, target, kit, roundCount);
challenger.sendMessage("§aDuel challenge sent to " + target.getName());
}
Example 4: Queueing a Player and Reading Queue State
Add a player to a kit queue programmatically and inspect how many players are waiting:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.kit.Kit;
import com.shyamstudio.shyamduels.queue.QueueMode;
import org.bukkit.entity.Player;
public void quickQueue(Player player, String kitName) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
Kit kit = api.kits().getKit(kitName);
if (kit == null) return;
if (api.queue().isQueued(player)) {
api.queue().removePlayer(player);
player.sendMessage("§eLeft the queue.");
return;
}
api.queue().addPlayer(player, kit, QueueMode.ONE_V_ONE);
int waiting = api.queue().getQueueSize(kitName, QueueMode.ONE_V_ONE);
player.sendMessage("§aQueued for " + kitName + " §7(" + waiting + " waiting)");
}
Example 5: Refreshing Display Elements and Playing the Match-Found Animation
Use the tab, scoreboard, nametag, and animation services to refresh a player's HUD and play the totem match-found pop:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.kit.Kit;
import org.bukkit.entity.Player;
public void refreshDisplays(Player player, String kitName) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Tab list, scoreboard, and nametags
api.tab().refreshTab(player);
api.scoreboard().refresh(player);
api.nameTags().refresh(player);
// Play a configured title animation by name
if (api.animations().has("queue-found-animation")) {
api.animations().play(player, "queue-found-animation");
}
// Play the on-screen totem match-found pop showing the kit item
Kit kit = api.kits().getKit(kitName);
api.tab().playMatchFoundAnimation(player, kit != null ? kit.getIcon() : null);
}
Example 6: Working With Optional Modules (Custom Kits and Kit Editor)
Optional services are only present when their module is enabled, so resolve them through Optional:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import org.bukkit.entity.Player;
public void openCustomKitEditor(Player player) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Warm the player's custom kit cache, then open the practice kit editor
api.customKits().ifPresent(service -> service.preloadPlayerKits(player.getUniqueId()));
api.kitEditor().ifPresent(service -> service.openEditor(player));
// Practice features (golden head, totem practice, kit room)
api.practice().ifPresent(service -> {
service.giveGoldenHead(player, 1);
service.openKitRoom(player);
});
}
Example 7: Offering a Rematch After a Duel
Hook into your own duel-end logic and offer both opponents a rematch via the API:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.duel.Duel;
import org.bukkit.entity.Player;
public void offerRematch(Duel finishedDuel) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Only 1v1 duels are eligible; the service guards this internally
api.rematch().offerRematch(finishedDuel);
}
public void onRematchButtonClicked(Player player) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
api.rematch().handleRematchClick(player);
}
Example 8: Building Overall & Per-Kit Leaderboards
Fetch top players asynchronously for global rankings or filtered by a specific kit (e.g. nodebuff, boxing, gapple):
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.stats.KitLeaderboardEntry;
import com.shyamstudio.shyamduels.stats.PlayerStats;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
// 1. Overall ELO Leaderboard
public void showGlobalLeaderboard(Player viewer) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
api.stats().getTopPlayers("elo", 10).thenAccept(top -> {
Bukkit.getScheduler().runTask(api.getPlugin(), () -> {
viewer.sendMessage("§6=== Top 10 Overall ELO ===");
int rank = 1;
for (PlayerStats stats : top) {
viewer.sendMessage("§e#" + (rank++) + " §7" + stats.getUuid() + " §f- " + stats.getElo() + " ELO");
}
});
});
}
// 2. Per-Kit Leaderboard (e.g. Nodebuff ELO or Wins)
public void showKitLeaderboard(Player viewer, String kitName) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
api.stats().getTopPlayers(kitName, "elo", 10).thenAccept(top -> {
Bukkit.getScheduler().runTask(api.getPlugin(), () -> {
viewer.sendMessage("§6=== Top 10 for " + kitName + " ===");
int rank = 1;
for (KitLeaderboardEntry entry : top) {
viewer.sendMessage("§e#" + (rank++) + " §7" + entry.getPlayerUuid()
+ " §f- §b" + entry.getElo() + " ELO §7(Wins: " + entry.getWins() + ")");
}
});
});
}
Example 9: Reading Per-Kit & Overall Stats by Player / UUID
The convenience getters on StatsService let you read overall and per-kit stats for any cached player directly or via KitStats/PlayerStats without boilerplate. This is handy for PlaceholderAPI bridges, custom GUIs, or reward checks:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.stats.KitStats;
import org.bukkit.entity.Player;
import java.util.UUID;
public void showCombatSummary(Player viewer, UUID target, String kitName) {
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
// Overall stats
int globalElo = api.stats().getElo(target);
int globalWins = api.stats().getWins(target);
int globalKills = api.stats().getKills(target);
int globalDeaths = api.stats().getDeaths(target);
// Per-Kit stats & metrics
KitStats kitStats = api.stats().getKitStats(target, kitName);
int kitElo = kitStats.getElo();
int kitWins = kitStats.getWins();
int kitLosses = kitStats.getLosses();
double kitKd = kitStats.getKD();
double kitWinrate = kitStats.getWinRate();
viewer.sendMessage("§6=== Stats Summary for " + kitName + " ===");
viewer.sendMessage("§7Global: §f" + globalElo + " ELO §7| §f" + globalWins + " Wins §7| §f" + globalKills + " Kills");
viewer.sendMessage("§7Kit ELO: §b" + kitElo + " §7| Wins: §a" + kitWins + " §7| Losses: §c" + kitLosses);
viewer.sendMessage(String.format("§7Kit K/D: §f%.2f §7| Win Rate: §f%.1f%% §7| Streak: §e%d",
kitKd, kitWinrate, kitStats.getWinstreak()));
}
Example 10: Tracking Live Kills With FightDeathEvent
Combine the custom events with the stats getters to react to in-duel kills as they happen:
javaimport org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.duel.event.FightDeathEvent;
public class KillRewardListener implements Listener {
@EventHandler
public void onFightDeath(FightDeathEvent event) {
Player killer = event.getKiller();
if (killer == null) return;
ShyamDuelsAPI api = ShyamDuelsProvider.get();
if (api == null) return;
int totalKills = api.stats().getKills(killer.getUniqueId());
if (totalKills % 100 == 0) {
killer.sendMessage("§6Milestone! §fYou have reached " + totalKills + " total kills.");
}
}
}
Example 11: Reading Share Codes and Importing a Shared Kit
Use KitShareService to read an online owner's share code, then import that kit for
another player. Resolution and imports operate on online owners only, so call them on the main
thread; the resulting saves run asynchronously inside the managers:
javaimport com.shyamstudio.shyamduels.api.ShyamDuelsAPI;
import com.shyamstudio.shyamduels.api.ShyamDuelsProvider;
import com.shyamstudio.shyamduels.api.kitshare.KitShareService;
import com.shyamstudio.shyamduels.kit.KitShareManager;
import org.bukkit.entity.Player;
public class KitShareExample {
public void shareInfo(Player owner, String kitName) {
ShyamDuelsAPI api = ShyamDuelsProvider.require();
KitShareService share = api.kitShare();
if (!share.isSharing(owner.getUniqueId())) {
owner.sendMessage("§cYou have kit sharing disabled. Enable it in /settings.");
return;
}
String code = share.getShareCode(owner.getUniqueId(), kitName);
int imports = share.getImportCount(owner.getUniqueId(), kitName);
owner.sendMessage("§aCode: §f" + code + " §7(" + imports + " imports)");
}
public void importFromCode(Player importer, String code) {
ShyamDuelsAPI api = ShyamDuelsProvider.require();
KitShareService share = api.kitShare();
// Inspect the reference first (optional)
KitShareManager.ShareRef ref = share.resolve(code);
if (ref == null) {
importer.sendMessage("§cUnknown share code, or the owner is offline.");
return;
}
// Performs all checks and messages the importer on success/failure
share.importKit(importer, code);
}
}