Appearance
Developer API
CrestPayouts provides a comprehensive API that allows developers to interact with the payout system. This enables you to trigger payouts programmatically, access player statistics, and integrate with the plugin's functionality.
Adding as a Dependency
To use the CrestPayouts API in your plugin, you need to add the plugin JAR to your development environment:
Manual JAR Dependency
- Download the CrestPayouts.jar
- Add it to your project's libraries
For Maven:
xml
<dependencies>
<dependency>
<groupId>me.levitate</groupId>
<artifactId>CrestPayouts</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/CrestPayouts.jar</systemPath>
</dependency>
</dependencies>
For Gradle:
kotlin
dependencies {
compileOnly(files("libs/CrestPayouts.jar"))
}
Server Setup
Make sure CrestPayouts is installed on your server and loaded before your plugin. Add it to your plugin.yml dependencies:
yaml
depend: [CrestPayouts]
# or for soft dependency
softdepend: [CrestPayouts]
API Structure
The CrestPayouts API is divided into two main classes:
- CrestPayoutsAPI - Main API class that provides access to core functionality
- PayoutAPI - Specialized API for working directly with payouts
Accessing the API
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.api.PayoutAPI;
public class YourPlugin extends JavaPlugin {
@Override
public void onEnable() {
// Get the CrestPayoutsAPI instance
CrestPayoutsAPI api = CrestPayoutsAPI.getInstance();
// Or get the PayoutAPI for payout-specific operations
PayoutAPI payoutAPI = api.getPayoutAPI();
// Now you can use the API
}
}
Basic Examples
Triggering a Payout
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.api.PayoutAPI;
import me.levitate.crestPayouts.api.models.PayoutResult;
public boolean triggerPayout(String payoutType) {
// Get the API
PayoutAPI payoutAPI = CrestPayoutsAPI.getInstance().getPayoutAPI();
// Check if the payout type exists
if (!payoutAPI.isValidPayoutType(payoutType)) {
return false;
}
// Execute the payout
PayoutResult result = payoutAPI.executePayout(payoutType);
return result.isSuccess();
}
Asynchronous Payout Execution
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.api.PayoutAPI;
import me.levitate.crestPayouts.api.models.PayoutResult;
public void triggerPayoutAsync(String payoutType, Consumer<PayoutResult> callback) {
// Get the API
PayoutAPI payoutAPI = CrestPayoutsAPI.getInstance().getPayoutAPI();
// Execute the payout asynchronously
payoutAPI.executePayoutAsync(payoutType).thenAccept(result -> {
if (result.isSuccess()) {
getLogger().info("Payout executed successfully with " +
result.getPlayerCount() + " winners");
} else {
getLogger().warning("Payout failed: " + result.getMessage());
}
// Call the callback with the result
callback.accept(result);
});
}
Working with Player Statistics
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import org.bukkit.entity.Player;
import java.util.Map;
public void showPlayerStats(Player player) {
// Get the API
CrestPayoutsAPI api = CrestPayoutsAPI.getInstance();
// Get a specific statistic
Double balance = api.getPlayerPlaceholderValue(player.getUniqueId(), "vault_eco_balance");
if (balance != null) {
player.sendMessage("Your current balance: $" + balance);
}
// Get all tracked statistics
Map<String, Double> allStats = api.getPlayerStats(player.getUniqueId());
player.sendMessage("Your tracked statistics:");
for (Map.Entry<String, Double> entry : allStats.entrySet()) {
player.sendMessage(" - " + entry.getKey() + ": " + entry.getValue());
}
}
Modifying Player Statistics
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import org.bukkit.entity.Player;
public void setCustomStatistic(Player player, String placeholder, double value) {
// Get the API
CrestPayoutsAPI api = CrestPayoutsAPI.getInstance();
// Set the value
api.setPlayerPlaceholderValue(player.getUniqueId(), placeholder, value);
player.sendMessage("Your " + placeholder + " statistic has been set to " + value);
}
Working with Leaderboards
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.models.LeaderboardEntry;
import org.bukkit.entity.Player;
import java.util.List;
public void showLeaderboard(Player player, String payoutType, int limit) {
// Get the API
CrestPayoutsAPI api = CrestPayoutsAPI.getInstance();
// Get the leaderboard
List<LeaderboardEntry> leaderboard = api.getLeaderboard(payoutType, limit);
// Show the leaderboard to the player
player.sendMessage("Top " + limit + " players for " + payoutType + ":");
for (int i = 0; i < leaderboard.size(); i++) {
LeaderboardEntry entry = leaderboard.get(i);
player.sendMessage((i+1) + ". " + entry.playerName() + " - " + entry.value());
}
}
Getting Next Payout Time
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import org.bukkit.entity.Player;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public void showNextPayoutTime(Player player, String payoutType) {
// Get the API
CrestPayoutsAPI api = CrestPayoutsAPI.getInstance();
// Get the next payout time
LocalDateTime nextTime = api.getNextPayoutTime(payoutType);
if (nextTime != null) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy 'at' HH:mm");
player.sendMessage("Next " + payoutType + " payout: " + nextTime.format(formatter));
} else {
player.sendMessage("No scheduled payout found for " + payoutType);
}
}
Handling Pending Rewards
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.api.PayoutAPI;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class RewardListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
// Get the API
PayoutAPI payoutAPI = CrestPayoutsAPI.getInstance().getPayoutAPI();
// Process any pending rewards for the player
int rewardsGiven = payoutAPI.givePendingRewards(player);
if (rewardsGiven > 0) {
player.sendMessage("You received " + rewardsGiven + " pending rewards while you were offline!");
}
}
}
Available API Methods
CrestPayoutsAPI Methods
java
// Get a player's value for a specific placeholder
Double getPlayerPlaceholderValue(UUID uuid, String placeholder);
// Set a player's value for a specific placeholder
void setPlayerPlaceholderValue(UUID uuid, String placeholder, double value);
// Get the player's current statistics for all tracked placeholders
Map<String, Double> getPlayerStats(UUID uuid);
// Get all payout types configured in the plugin
Map<String, PayoutsConfig.PayoutEntry> getConfiguredPayouts();
// Get the leaderboard for a specific payout type
List<LeaderboardEntry> getLeaderboard(String payoutType, int limit);
// Get the time of the next scheduled payout for a specific payout type
LocalDateTime getNextPayoutTime(String payoutType);
// Get the PayoutAPI instance
PayoutAPI getPayoutAPI();
PayoutAPI Methods
java
// Triggers a payout for a specific payout type
PayoutResult executePayout(String payoutType);
// Asynchronously triggers a payout for a specific payout type
CompletableFuture<PayoutResult> executePayoutAsync(String payoutType);
// Gives all pending rewards to a player
int givePendingRewards(Player player);
// Checks if a payout type exists
boolean isValidPayoutType(String payoutType);
// Schedules a one-time refresh of a player's stats after a delay
void scheduleStatsRefresh(Player player, long delayTicks);
API Events
CrestPayouts provides several events that you can listen for in your plugin:
PayoutEvent
Called before a payout is executed. This event is cancellable.
java
import me.levitate.crestPayouts.api.events.PayoutEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PayoutEventListener implements Listener {
@EventHandler
public void onPayout(PayoutEvent event) {
// Get the payout type and display name
String payoutType = event.getPayoutType();
String displayName = event.getPayoutDisplayName();
// Log the event
getLogger().info("Payout triggered: " + displayName + " (" + payoutType + ")");
// Optionally cancel the event
if (shouldCancel(payoutType)) {
event.setCancelled(true);
getLogger().info("Cancelled payout: " + payoutType);
}
}
private boolean shouldCancel(String payoutType) {
// Your logic to determine if the payout should be cancelled
return false;
}
}
PayoutLeaderboardGenerateEvent
Called when a leaderboard is generated for a payout. Allows modification of the leaderboard before rewards are processed.
java
import me.levitate.crestPayouts.api.events.PayoutLeaderboardGenerateEvent;
import me.levitate.crestPayouts.models.LeaderboardEntry;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class LeaderboardListener implements Listener {
@EventHandler
public void onLeaderboardGenerate(PayoutLeaderboardGenerateEvent event) {
// Get the payout type
String payoutType = event.getPayoutType();
// Get the leaderboard
List<LeaderboardEntry> leaderboard = event.getLeaderboard();
// Modify the leaderboard
// For example, add bonus points for VIP players
for (int i = 0; i < leaderboard.size(); i++) {
LeaderboardEntry entry = leaderboard.get(i);
// Check if the player is a VIP and add bonus points
if (isVipPlayer(entry.uuid())) {
double newValue = entry.value() * 1.1; // 10% bonus
LeaderboardEntry newEntry = new LeaderboardEntry(
entry.uuid(),
entry.playerName(),
newValue
);
// Replace the entry with the modified one
leaderboard.set(i, newEntry);
}
}
// Update the leaderboard
event.setLeaderboard(leaderboard);
}
private boolean isVipPlayer(UUID uuid) {
// Your logic to check if a player is VIP
return false;
}
}
PayoutRewardEvent
Called before a player receives a payout reward. This event is cancellable and allows modification of the reward.
java
import me.levitate.crestPayouts.api.events.PayoutRewardEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.List;
import java.util.UUID;
public class RewardListener implements Listener {
@EventHandler
public void onPayoutReward(PayoutRewardEvent event) {
// Get event information
String payoutType = event.getPayoutType();
String displayName = event.getPayoutDisplayName();
UUID playerUUID = event.getPlayerUUID();
String playerName = event.getPlayerName();
int rank = event.getRank();
double value = event.getPlayerValue();
String rewardSummary = event.getRewardSummary();
// Get the reward commands (can be modified)
List<String> commands = event.getCommands();
// Example: Add an extra reward for first place
if (rank == 1) {
commands.add("broadcast &6" + playerName + " just received the #1 " + displayName + " reward!");
commands.add("give " + playerName + " diamond 10");
}
// Example: Modify the message
String message = event.getMessage();
message = message + " &aYou ranked #" + rank + " out of all players!";
event.setMessage(message);
// Example: Cancel the reward for a specific player
if (playerName.equals("BadPlayer")) {
event.setCancelled(true);
}
}
}
API Models
The CrestPayouts API includes several model classes that represent data structures used by the plugin:
LeaderboardEntry
Represents an entry in a payout leaderboard.
java
public class LeaderboardEntry {
private final UUID uuid; // Player UUID
private final String playerName; // Player name
private final double value; // Player's value for the statistic
// Methods (using Lombok @Accessors(fluent = true))
public UUID uuid() { ... }
public String playerName() { ... }
public double value() { ... }
}
PayoutResult
Represents the result of a payout operation.
java
public class PayoutResult {
private final boolean success; // Whether the payout was successful
private final List<LeaderboardEntry> leaderboard; // The leaderboard for the payout
private final String message; // A message describing the result
// Methods
public boolean isSuccess() { ... }
public List<LeaderboardEntry> getLeaderboard() { ... }
public String getMessage() { ... }
public int getPlayerCount() { ... } // Number of players that received rewards
}
PendingReward
Represents a reward that is pending delivery to a player.
java
public class PendingReward {
private String payoutType; // The ID of the payout type
private String payoutDisplayName; // The display name of the payout
private int rank; // The player's rank
private List<String> commands; // The commands to execute
private String message; // The message to send to the player
// Methods (using Lombok @Accessors(fluent = true))
public String payoutType() { ... }
public String payoutDisplayName() { ... }
public int rank() { ... }
public List<String> commands() { ... }
public String message() { ... }
}
PlayerStats
Represents a player's statistics for tracked placeholders.
java
public class PlayerStats {
private long lastUpdate; // Last update timestamp
private Map<String, Double> placeholderValues; // Map of placeholder to value
// Methods (using Lombok @Accessors(fluent = true))
public long lastUpdate() { ... }
public Map<String, Double> placeholderValues() { ... }
}
Best Practices
- Error Handling: Always check for null values and handle exceptions when working with the API
- Asynchronous Operations: Use asynchronous methods when possible to avoid blocking the main thread
- Resource Management: Clean up any resources you create (like event listeners)
- Permission Checks: Ensure players have appropriate permissions before using API methods
- Configuration Validation: Validate any custom payout configurations you create
Example Plugin Integration
Here's a complete example of a plugin that integrates with CrestPayouts:
java
import me.levitate.crestPayouts.api.CrestPayoutsAPI;
import me.levitate.crestPayouts.api.PayoutAPI;
import me.levitate.crestPayouts.api.events.PayoutEvent;
import me.levitate.crestPayouts.api.models.PayoutResult;
import me.levitate.crestPayouts.models.LeaderboardEntry;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
public class MyPlugin extends JavaPlugin implements Listener {
private CrestPayoutsAPI payoutsAPI;
@Override
public void onEnable() {
// Check if CrestPayouts is available
if (getServer().getPluginManager().getPlugin("CrestPayouts") == null) {
getLogger().warning("CrestPayouts not found! Some features will be disabled.");
return;
}
// Get the API
this.payoutsAPI = CrestPayoutsAPI.getInstance();
// Register event listener
getServer().getPluginManager().registerEvents(this, this);
getLogger().info("Successfully hooked into CrestPayouts API!");
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (label.equalsIgnoreCase("myplugin")) {
if (!(sender instanceof Player)) {
sender.sendMessage("This command can only be used by players.");
return true;
}
Player player = (Player) sender;
if (args.length == 0) {
// Show help message
sender.sendMessage("§6§lMyPlugin Commands:");
sender.sendMessage("§e/myplugin stats §7- Show your payout statistics");
sender.sendMessage("§e/myplugin leaderboard <type> §7- Show a leaderboard");
sender.sendMessage("§e/myplugin next <type> §7- Show next payout time");
return true;
}
// Handle command arguments
switch (args[0].toLowerCase()) {
case "stats":
showPlayerStats(player);
break;
case "leaderboard":
if (args.length < 2) {
player.sendMessage("§cUsage: /myplugin leaderboard <type>");
return true;
}
showLeaderboard(player, args[1]);
break;
case "next":
if (args.length < 2) {
player.sendMessage("§cUsage: /myplugin next <type>");
return true;
}
showNextPayout(player, args[1]);
break;
default:
player.sendMessage("§cUnknown command. Use /myplugin for help.");
}
return true;
}
return false;
}
private void showPlayerStats(Player player) {
if (payoutsAPI == null) {
player.sendMessage("§cCrestPayouts not available!");
return;
}
player.sendMessage("§6§lYour Statistics:");
payoutsAPI.getConfiguredPayouts().forEach((id, config) -> {
Double value = payoutsAPI.getPlayerPlaceholderValue(player.getUniqueId(), config.placeholder);
player.sendMessage("§e" + config.displayName + ": §f" + (value != null ? value : "Not tracked"));
});
}
private void showLeaderboard(Player player, String payoutType) {
if (payoutsAPI == null) {
player.sendMessage("§cCrestPayouts not available!");
return;
}
PayoutAPI payoutAPI = payoutsAPI.getPayoutAPI();
if (!payoutAPI.isValidPayoutType(payoutType)) {
player.sendMessage("§cInvalid payout type: " + payoutType);
return;
}
String displayName = payoutsAPI.getConfiguredPayouts().get(payoutType).displayName;
List<LeaderboardEntry> leaderboard = payoutsAPI.getLeaderboard(payoutType, 10);
player.sendMessage("§6§lTop 10 - " + displayName);
if (leaderboard.isEmpty()) {
player.sendMessage("§cNo data available for this leaderboard.");
return;
}
for (int i = 0; i < leaderboard.size(); i++) {
LeaderboardEntry entry = leaderboard.get(i);
player.sendMessage("§e#" + (i+1) + " §f" + entry.playerName() + " §7- §f" + entry.value());
}
}
private void showNextPayout(Player player, String payoutType) {
if (payoutsAPI == null) {
player.sendMessage("§cCrestPayouts not available!");
return;
}
PayoutAPI payoutAPI = payoutsAPI.getPayoutAPI();
if (!payoutAPI.isValidPayoutType(payoutType)) {
player.sendMessage("§cInvalid payout type: " + payoutType);
return;
}
String displayName = payoutsAPI.getConfiguredPayouts().get(payoutType).displayName;
LocalDateTime nextTime = payoutsAPI.getNextPayoutTime(payoutType);
if (nextTime == null) {
player.sendMessage("§cNo scheduled payout found for " + displayName);
return;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy 'at' HH:mm");
player.sendMessage("§6Next " + displayName + " payout: §f" + nextTime.format(formatter));
}
@EventHandler
public void onPayout(PayoutEvent event) {
// Log payout events
getLogger().info("Payout triggered: " + event.getPayoutDisplayName());
}
}