Integrasi Plugin dengan RankForge API – Contoh Kode Lengkap
Halaman ini berisi contoh siap salin untuk mengintegrasikan plugin kamu dengan RankForge. Pastikan sudah menyelesaikan Setup Dependency.
Skeleton plugin dengan integrasi RankForge
Section titled “Skeleton plugin dengan integrasi RankForge”Struktur proyek:
Directorysrc/main/
Directoryjava/com/example/myplugin/
- MyPlugin.java
- RankForgeHook.java
Directoryresources/
- plugin.yml
name: MyPluginversion: 1.0.0main: com.example.myplugin.MyPluginapi-version: '1.21'folia-supported: truesoftdepend: [RankForge]commands: mystats: description: Lihat statistik RankForge kamu usage: /mystatspackage com.example.myplugin;
import org.bukkit.plugin.java.JavaPlugin;
public class MyPlugin extends JavaPlugin {
private RankForgeHook rankForgeHook;
@Override public void onEnable() { // Jangan referensikan class RankForge di sini; cukup di RankForgeHook if (getServer().getPluginManager().isPluginEnabled("RankForge")) { rankForgeHook = new RankForgeHook(this); rankForgeHook.register(); getLogger().info("Integrasi RankForge aktif."); } else { getLogger().warning("RankForge tidak ditemukan, fitur ranking dimatikan."); } }}package com.example.myplugin;
import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import xyz.noxlydev.rankforge.api.IRankForgeAPI;import xyz.noxlydev.rankforge.api.RankForgeAPI;import xyz.noxlydev.rankforge.api.event.PlayerTierUpEvent;
public class RankForgeHook implements Listener {
private final MyPlugin plugin; private final IRankForgeAPI api;
public RankForgeHook(MyPlugin plugin) { this.plugin = plugin; this.api = RankForgeAPI.get(); }
public void register() { plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getCommand("mystats").setExecutor((sender, cmd, label, args) -> { if (sender instanceof Player p) { showStats(p); } return true; }); }
private void showStats(Player p) { var tier = api.getTier(p); var next = api.getNextTier(p); p.sendMessage("§6Poin: §f" + api.getPoints(p)); p.sendMessage("§6Tier: §f" + (tier != null ? tier.display : "Unranked")); p.sendMessage("§6K/D: §f" + String.format("%.2f", api.getKD(p.getUniqueId())) + " §7(" + api.getKills(p.getUniqueId()) + "/" + api.getDeaths(p.getUniqueId()) + ")"); p.sendMessage(next != null ? "§6Menuju §f" + next.display + "§6: §e" + (next.min - api.getPoints(p)) + " poin lagi" : "§6Kamu sudah di tier tertinggi!"); }
@EventHandler public void onTierUp(PlayerTierUpEvent event) { // lihat resep "Reward custom saat naik tier" di bawah }}Reward custom saat naik tier
Section titled “Reward custom saat naik tier”RankForge hanya menjalankan rewards: tier pada alur kill dan hanya sekali per tier. Untuk reward sendiri atau reward dari perubahan poin lewat API, dengarkan PlayerTierUpEvent. Karena event bisa terpicu lagi jika poin naik-turun, catat reward yang sudah kamu berikan.
import org.bukkit.NamespacedKey;import org.bukkit.persistence.PersistentDataContainer;import org.bukkit.persistence.PersistentDataType;
private NamespacedKey claimedKey() { return new NamespacedKey(plugin, "claimed_tiers");}
@EventHandlerpublic void onTierUp(PlayerTierUpEvent event) { Player player = event.getPlayer(); String tierId = event.getNewTier().id;
PersistentDataContainer pdc = player.getPersistentDataContainer(); String raw = pdc.getOrDefault(claimedKey(), PersistentDataType.STRING, ""); java.util.Set<String> claimed = new java.util.HashSet<>( raw.isEmpty() ? java.util.List.of() : java.util.List.of(raw.split(",")));
if (!claimed.add(tierId)) { return; // sudah pernah dapat reward ini } pdc.set(claimedKey(), PersistentDataType.STRING, String.join(",", claimed));
// Berikan reward kamu sendiri player.getInventory().addItem(new org.bukkit.inventory.ItemStack(org.bukkit.Material.DIAMOND, 8)); player.sendMessage("§aReward tier " + event.getNewTier().display + " §adiberikan!");}Bonus poin untuk aktivitas lain
Section titled “Bonus poin untuk aktivitas lain”Contoh: memberi poin saat pemain menyelesaikan event buatanmu. Panggil dari thread server.
public void rewardEventWinner(Player winner) { IRankForgeAPI api = RankForgeAPI.get(); api.addPoints(winner, 25); // memicu PlayerPointsChangeEvent, dan TierUp jika naik tier winner.sendMessage("§a+25 poin RankForge!");}Modifier poin (VIP multiplier)
Section titled “Modifier poin (VIP multiplier)”@EventHandlerpublic void onPointsChange(PlayerPointsChangeEvent event) { if (event.getDifference() <= 0) return;
Player online = event.getPlayer().getPlayer(); if (online != null && online.hasPermission("myplugin.vip")) { int extra = (int) Math.ceil(event.getDifference() * 0.10); event.setNewPoints(event.getNewPoints() + extra); }}Command top pemain
Section titled “Command top pemain”import xyz.noxlydev.rankforge.model.PlayerData;import xyz.noxlydev.rankforge.model.Tier;
public void sendTop(CommandSender sender, int limit) { IRankForgeAPI api = RankForgeAPI.get(); int pos = 1; for (PlayerData data : api.getTopPlayers(limit)) { Tier tier = api.getTierByPoints(data.getPoints()); sender.sendMessage("§e#" + pos++ + " §f" + data.getName() + " §8- §6" + data.getPoints() + " Pts §8(" + (tier != null ? tier.display : "Unranked") + "§8)"); }}Placeholder buatan sendiri dari data RankForge
Section titled “Placeholder buatan sendiri dari data RankForge”Contoh expansion PlaceholderAPI milik plugin kamu yang menampilkan nama tier berikutnya: %myplugin_next_rank%.
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
public class MyExpansion extends PlaceholderExpansion { @Override public String getIdentifier() { return "myplugin"; } @Override public String getAuthor() { return "KamuDev"; } @Override public String getVersion() { return "1.0.0"; } @Override public boolean persist() { return true; }
@Override public String onRequest(org.bukkit.OfflinePlayer player, String params) { if (player == null || !RankForgeAPI.isAvailable()) return ""; if (params.equalsIgnoreCase("next_rank")) { Tier next = RankForgeAPI.get().getNextTier(player); return next != null ? next.display : "MAX"; } return null; }}Dipanggil dari thread async (termasuk Folia)
Section titled “Dipanggil dari thread async (termasuk Folia)”Method tulis (setPoints, dll.) memicu event sinkron, jadi harus berjalan di thread server. Dari kode async, pindahkan eksekusinya dengan scheduler global yang tersedia di Paper dan Folia:
CompletableFuture.supplyAsync(() -> fetchRewardFromWebApi(player.getUniqueId())) .thenAccept(amount -> Bukkit.getGlobalRegionScheduler().execute(plugin, () -> RankForgeAPI.get().addPoints(player.getUniqueId(), amount) ));Pastikan folia-supported: true ada di plugin.yml plugin kamu jika ingin berjalan di Folia.
Contoh Kotlin
Section titled “Contoh Kotlin”import xyz.noxlydev.rankforge.api.RankForgeAPI
fun tierName(player: Player): String { if (!RankForgeAPI.isAvailable()) return "N/A" return RankForgeAPI.get().getTier(player)?.display ?: "Unranked"}Alternatif tanpa dependency: PlaceholderAPI
Section titled “Alternatif tanpa dependency: PlaceholderAPI”Kalau kamu hanya perlu membaca nilai (bukan mengubah), tidak perlu dependency kode sama sekali. Pakai PlaceholderAPI:
String points = PlaceholderAPI.setPlaceholders(player, "%rankforge_points%");Cocok untuk plugin yang sudah bergantung pada PlaceholderAPI. Daftar placeholder: PlaceholderAPI.
