BlazeBans API/Getting started
Getting the API
`BlazeBansProvider` is a static holder. BlazeBans registers itself into it when it enables, and clears it when it disables.
The three accessors
BlazeBansApi api = BlazeBansProvider.get(); // throws if unavailable
Optional<BlazeBansApi> maybe = BlazeBansProvider.optional();
boolean ready = BlazeBansProvider.available();Which one to use depends entirely on whether you declared a hard or soft dependency.
With a hard dependency
If your plugin.yml has depend: [BlazeBans], Paper guarantees BlazeBans enabled before you. get() is safe in onEnable, and letting it throw is the correct behaviour: something is wrong with the install and failing loudly is better than running half-broken.
public final class MyAddon extends JavaPlugin {
private BlazeBansApi blazeBans;
@Override
public void onEnable() {
this.blazeBans = BlazeBansProvider.get();
getLogger().info("Hooked into BlazeBans " + this.blazeBans.version());
}
}There is one case a hard dependency does not cover: hooks.api: false in settings.yml. BlazeBans then enables normally but never registers the API. Handling it with a clear message saves a support conversation:
@Override
public void onEnable() {
this.blazeBans = BlazeBansProvider.optional().orElse(null);
if (this.blazeBans == null) {
getLogger().severe("The BlazeBans API is unavailable. Set hooks.api to true in "
+ "plugins/BlazeBans/settings.yml and restart.");
getServer().getPluginManager().disablePlugin(this);
return;
}
getLogger().info("Hooked into BlazeBans " + this.blazeBans.version());
}Disabling yourself is usually right for an addon. A plugin whose only job is extending BlazeBans has nothing to do without it, and staying enabled just moves the error to a confusing place later.
With a soft dependency
If BlazeBans support is optional in your plugin, you cannot cache the instance in onEnable and trust it. Two things can go wrong: BlazeBans may not be installed, and with softdepend it may enable after you.
Look it up at the point of use instead:
public final class MyPlugin extends JavaPlugin {
private Optional<BlazeBansApi> blazeBans() {
return BlazeBansProvider.optional();
}
public void onSomethingHappened(Player player) {
blazeBans().ifPresentOrElse(
api -> api.punishments()
.isMuted(player.getName(), player.getUniqueId())
.thenAccept(muted -> { /* ... */ }),
() -> { /* BlazeBans is not here; carry on without it */ }
);
}
}The lookup is a single atomic read, so calling it per use costs nothing worth optimising. Caching it is what causes the bugs.
Availability over time
That last row matters. During shutdown, plugins disable in reverse dependency order, so BlazeBans may already be gone by the time your onDisable runs. Do not assume the API is there:
@Override
public void onDisable() {
BlazeBansProvider.unregisterAddon("MyAddon");
// Do not call this.blazeBans.punishments() here. It may be shutting down,
// and a database write started now is not guaranteed to finish.
}Unregistering your addon metadata is safe and correct. Starting new work is not.
Do not register anything
BlazeBansProvider.register(api); // BlazeBans only
BlazeBansProvider.unregister(api); // BlazeBans onlyThese exist because BlazeBans needs them. Calling either from a consumer plugin replaces or clears the live API for every other plugin on the server.
registerAddon and unregisterAddon are the pair you are meant to call. They only touch your own metadata. See What an addon is.
Version checks
getLogger().info("BlazeBans " + api.version());version() returns the running version as a string, the same one /blazebans version shows.
It is fine for logging. Do not parse it to gate features: the API is compiled against, so if a method exists at compile time it exists at runtime, and a class that would have been removed would have failed the release build. If you need to support an older BlazeBans that genuinely lacks something, catch NoSuchMethodError around the call rather than comparing version strings.
A complete safe startup
package com.example.myaddon;
import net.blazebans.api.BlazeBansApi;
import net.blazebans.api.BlazeBansProvider;
import net.blazebans.api.addon.BlazeBansAddon;
import org.bukkit.plugin.java.JavaPlugin;
public final class MyAddon extends JavaPlugin {
private static final String ADDON_ID = "MyAddon";
private BlazeBansApi blazeBans;
@Override
public void onEnable() {
this.blazeBans = BlazeBansProvider.optional().orElse(null);
if (this.blazeBans == null) {
getLogger().severe("The BlazeBans API is unavailable. Check hooks.api in settings.yml.");
getServer().getPluginManager().disablePlugin(this);
return;
}
BlazeBansProvider.registerAddon(new BlazeBansAddon(
ADDON_ID,
"My Addon",
getPluginMeta().getVersion(),
"Does something useful with punishments.",
"enabled"
));
getServer().getPluginManager().registerEvents(new MyListener(this.blazeBans), this);
getLogger().info("Hooked into BlazeBans " + this.blazeBans.version());
}
@Override
public void onDisable() {
BlazeBansProvider.unregisterAddon(ADDON_ID);
}
}Next: Threading, which is the part that decides whether your plugin is safe.

