Promotion background
Easter Season 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 about 2 hours 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
This site uses cookies to personalize content, enhance your experience. By continuing, you agree to our cookie use. Learn more