Promotion background
Summer Sale IS HERE!
10% off limited time offer!
Ends in
00
H
00
M
00
S
limited time offer SAVE 10% NOW โ†’
DEVELOPER ๐ŸŒ API

๐Ÿงช Examples

Practical examples of what you can and cannot do with the Phoenix Crates API.

triangle-exclamation

These examples target the public API module and are written to avoid depending on internal classes.

#1) Listen and override reward selection

Use CrateRewardSelectionEvent to choose a reward yourself.

import com.phoenixplugins.phoenixcrates.api.crate.events.CrateRewardSelectionEvent;
import com.phoenixplugins.phoenixcrates.api.reward.BaseReward;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

import java.util.Comparator;

public final class RewardSelectionListener implements Listener {

    @EventHandler
    public void onRewardSelection(CrateRewardSelectionEvent event) {
        BaseReward best = event.getCandidates().stream()
                .max(Comparator.comparingDouble(BaseReward::getWeight))
                .orElse(null);

        if (best != null) {
            event.setSelectedReward(best);
            event.setHandled(true);
        }
    }
}

Do not set only selectedReward and forget handled, otherwise the default flow can still replace your choice.

#2) Validate opening attempts before they start

Use CratePreOpenEvent when you want to block a crate opening with your own checks.

import com.phoenixplugins.phoenixcrates.api.crate.events.CratePreOpenEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class OpenGuardListener implements Listener {

    @EventHandler
    public void onPreOpen(CratePreOpenEvent event) {
        if (!event.getPlayer().hasPermission("myaddon.open")) {
            event.setCancelled(true);
            event.getPlayer().sendMessage("You cannot open this crate right now.");
        }
    }
}

#3) Query crates from the manager

Access the manager through PhoenixCratesAPI.

import com.phoenixplugins.phoenixcrates.api.PhoenixCratesAPI;
import com.phoenixplugins.phoenixcrates.api.crate.CrateType;

import java.util.List;

public final class CratesDebugService {

    public List<? extends CrateType> getEnabledTypes() {
        return PhoenixCratesAPI.getCratesManager().getCrateTypes();
    }

    public int getRegisteredCount() {
        return PhoenixCratesAPI.getCratesManager().countRegisteredTypes();
    }
}

#4) Inject a custom player data layer

The player data layer supports chain-of-responsibility style custom caching.

import com.phoenixplugins.phoenixcrates.api.PhoenixCratesAPI;
import com.phoenixplugins.phoenixcrates.api.player.PlayerDataLayer;
import com.phoenixplugins.phoenixcrates.api.player.PlayerDbModel;

import java.util.UUID;
import java.util.concurrent.CompletableFuture;

public final class MyDataLayer implements PlayerDataLayer {

    private PlayerDataLayer next;

    @Override
    public CompletableFuture<? extends PlayerDbModel> fetchByUniqueId(UUID uniqueId) {
        return next == null
                ? CompletableFuture.completedFuture(null)
                : next.fetchByUniqueId(uniqueId);
    }

    @Override
    public <T extends PlayerDbModel> CompletableFuture<T> insert(T model) {
        return next.insert(model);
    }

    @Override
    public <T extends PlayerDbModel> CompletableFuture<Void> update(T model) {
        return next.update(model);
    }

    @Override
    public void setNextLayer(PlayerDataLayer nextLayer) {
        this.next = nextLayer;
    }

    @Override
    public PlayerDataLayer getNextLayer() {
        return this.next;
    }
}

// During addon load:
// PhoenixCratesAPI.getPlayersManager().setPlayerDataLayer(new MyDataLayer());

Do not block the main thread waiting for CompletableFuture results.

#5) Read player crate data safely

Use the async fetch API for offline/online players.

import com.phoenixplugins.phoenixcrates.api.PhoenixCratesAPI;
import org.bukkit.OfflinePlayer;

public final class PlayerDataService {

    public void loadData(OfflinePlayer player) {
        PhoenixCratesAPI.getPlayersManager()
                .fetchPlayerDataAsync(player)
                .thenAccept(data -> {
                    if (data != null) {
                        // Read fields/modules from your callback.
                    }
                });
    }
}

#6) Track openings and rerolls for analytics

Listen to open and reroll events for metrics or logs.

import com.phoenixplugins.phoenixcrates.api.crate.events.CrateOpenEvent;
import com.phoenixplugins.phoenixcrates.api.crate.events.CrateRerollEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class AnalyticsListener implements Listener {

    @EventHandler
    public void onOpen(CrateOpenEvent event) {
        // Store event.getPlayer().getUniqueId() + event.getCrate().getType().getIdentifier()
    }

    @EventHandler
    public void onReroll(CrateRerollEvent event) {
        // Store event.getPreviousReward().getIdentifier() -> event.getNewReward().getIdentifier()
    }
}

#7) Customize final item delivery

Use ItemDeliveryEvent to edit or consume the list of items before they are delivered.

import com.phoenixplugins.phoenixcrates.api.events.items.ItemDeliveryEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;

import java.util.ArrayList;
import java.util.List;

public final class ItemDeliveryListener implements Listener {

    @EventHandler
    public void onDelivery(ItemDeliveryEvent event) {
        List<ItemStack> filtered = new ArrayList<>(event.getRemainingItemsSnapshot());
        filtered.removeIf(item -> item.getAmount() <= 0);
        event.setRemainingItems(filtered);
    }
}

#8) Inspect and manage animation phases

Use the animation registry to discover or register phases.

import com.phoenixplugins.phoenixcrates.api.PhoenixCratesAPI;
import com.phoenixplugins.phoenixcrates.api.crate.animation.AnimationPhase;
import com.phoenixplugins.phoenixcrates.api.crate.animation.PhaseType;

import java.util.Collection;
import java.util.Optional;

public final class AnimationRegistryService {

    public Collection<AnimationPhase> getOpeningPhases() {
        return PhoenixCratesAPI.getAnimationsRegistry().getPhases(PhaseType.OPENING);
    }

    public Optional<AnimationPhase> findById(String id) {
        return PhoenixCratesAPI.getAnimationsRegistry().getPhaseById(PhaseType.OPENING, id);
    }
}

#What is not supported by API-only integrations

  • Do not depend on internal classes from plugin modules outside com.phoenixplugins.phoenixcrates.api.*.
  • Do not call methods marked internal/unsafe unless you are maintaining plugin internals.
  • Do not assume constructor availability for concrete runtime implementations.
  • Do not override the full opening flow by reflection; use events and managers instead.
Last updated 3 months ago
My Cart (0 items)

Oops... looks like the spiders padded through here

Add products to your cart and remove them from here Lets buy