Developer API

Other plugins can read and change balances in any Obfeco currency, create or delete currencies, and react to balance changes. The API is the ObfecoAPI class and the CurrencyChangeEvent event, in net.busybee.obfeco.api.

If you only need the primary currency, use Vault instead and you don't depend on Obfeco at all.

Setup

Add Obfeco to your plugin.yml so it loads first:

yaml
softdepend: [Obfeco]

Obfeco isn't published to a Maven repository. Compile against the release jar from Modrinth as a provided / compileOnly dependency, and don't shade it.

Get the API from onEnable or later:

java
Obfeco obfeco = (Obfeco) Bukkit.getPluginManager().getPlugin("Obfeco");
ObfecoAPI api = obfeco.getApi();

Obfeco.getInstance().getApi() works too.

Balances

All balance methods return a CompletableFuture. Players who aren't loaded are read from storage first, so don't call .join() on the main thread.

Method Returns
getBalance(UUID player, String currencyId) Double balance
hasBalance(UUID player, String currencyId, double amount) Boolean, balance ≥ amount
addBalance(UUID player, String currencyId, double amount) Boolean success
removeBalance(UUID player, String currencyId, double amount) Boolean; false if it would go below zero
setBalance(UUID player, String currencyId, double amount) Boolean success
java
api.removeBalance(player.getUniqueId(), "gems", 50).thenAccept(ok -> {
    if (!ok) {
        // not enough gems, or the currency doesn't exist
    }
});

addBalance and removeBalance send the player the currency's receive/lose message when notify-give / notify-take is on. Changes are saved with the next batch save, like any other.

Currencies

Method Returns
getCurrency(String id) Currency or null
getCurrencies() Every loaded Currency
currencyExists(String id) boolean
createCurrency(Currency currency) CompletableFuture<Boolean>; writes the currency file
deleteCurrency(String id) CompletableFuture<Boolean>; removes the currency and every balance in it

Currency has the fields of a currency file: id, displayName, symbol, format, material, startingBalance, useDecimals, notifyGive, notifyTake, category, subcategory, with getters and setters. Its all-args constructor takes them in that order.

CurrencyChangeEvent

Fired before a balance change is applied to an online player, on that player's thread (the main thread on Paper, the player's region on Folia). It's cancellable.

java
@EventHandler
public void onChange(CurrencyChangeEvent event) {
    if (event.getCurrencyId().equals("gems")
            && event.getChangeType() == CurrencyChangeEvent.ChangeType.ADD
            && event.getNewBalance() > 1_000_000) {
        event.setCancelled(true); // cap gems at a million
    }
}
Getter Description
getPlayer() The online player
getCurrencyId() Currency id
getOldBalance() Balance before the change
getNewBalance() Balance after the change
getChangeType() ADD, REMOVE or SET

Cancelling stops the change and the command or API call reports failure. Changing setNewBalance has no effect on the amount applied. Changes to offline players don't fire the event, and neither do Vault calls made from Obfeco's own database threads.