-
Notifications
You must be signed in to change notification settings - Fork 0
Developer API
EconGuard exposes a small public API so any plugin can report money movements into the shared ledger. Nothing here is tied to the Royal* suite — the API is generic.
The whole integration is one statement, and it's safe whether or not EconGuard is installed.
import com.mystipixel.econguard.api.*;
EconGuard.get().ifPresent(api -> api.record(
MoneyEvent.builder(player.getUniqueId(), player.getName())
.source(Sources.BANK) // bank pay auction shop admin interest other
.action("deposit") // free-form; shown in /eg history
.amount(amount) // positive magnitude (see note)
.incoming(false) // is the player RECEIVING money?
.build()));EconGuard.get() returns Optional<EconGuardAPI> via the Bukkit services manager — empty when EconGuard isn't installed. So the ifPresent above is the entire guard: no isPluginEnabled check, no soft-depend requirement, no reflection. Your plugin compiles and runs identically with or without EconGuard present.
// Seller receives money from a buyer via an auction sale:
EconGuard.get().ifPresent(api -> api.record(
MoneyEvent.builder(seller.getUniqueId(), seller.getName())
.source(Sources.AUCTION)
.action("sale")
.amount(price)
.incoming(true) // seller is RECEIVING
.counterparty(buyer.getUniqueId(), buyer.getName()) // the other party
.item("ecoitems:brazen_sword")
.note("won auction #1234")
.build()));Create with MoneyEvent.builder(UUID player, String playerName), then chain:
| Method | Default | Meaning |
|---|---|---|
.source(String) |
"other" |
Where the movement came from — use a Sources constant. |
.action(String) |
"transaction" |
Free-form label shown in /eg history (e.g. deposit, sale). |
.amount(double) |
0 |
The magnitude. Stored as Math.abs(amount) — sign is ignored; use incoming for direction. |
.incoming(boolean) |
true |
true = money arrived to the player; false = money left them. |
.counterparty(UUID, String) |
none | The other party in a transfer, with their name. Omit when there isn't one. |
.item(String) |
none | Optional item id involved (e.g. an auction item). |
.balanceAfter(double) |
NaN |
Optional running balance after the movement; NaN if you don't track one. |
.note(String) |
none | Optional free-text note. |
.build() |
— | Produce the immutable MoneyEvent. |
public interface EconGuardAPI {
void record(MoneyEvent event); // persist + run anti-abuse analysis
List<Flag> getFlags(); // flags awaiting review
boolean clearFlag(UUID player); // clear one player's flag(s); true if any cleared
void clearFlags(); // clear all
List<MoneyEvent> getHistory(UUID player, int limit); // recent entries, newest first
}All methods are safe to call from the main server thread.
Conventional source labels. These are just strings — you may use any label — but sticking to the constants keeps histories consistent across plugins.
Sources.BANK // "bank"
Sources.PAY // "pay"
Sources.AUCTION // "auction"
Sources.SHOP // "shop"
Sources.ADMIN // "admin"
Sources.INTEREST // "interest"
Sources.OTHER // "other"public record Flag(
UUID player,
String playerName,
String type, // which signal fired
String reason, // human-readable explanation
long timestamp
) {}These are the two mistakes that quietly break detection:
A bank deposit is money leaving the player's purse → incoming(false). An auction sale pays the seller → incoming(true) on the seller's event. Get this backwards and the velocity and young-incoming signals point at the wrong side of every trade.
Counterparty correlation is the signal that catches RMT rings, and it goes silently dead if the field is null. A shop purchase has no counterparty (the server is the other side); a /pay or an auction sale absolutely does — record it, with both the UUID and the name.
EconGuard isn't on a public repo; add it as a provided dependency from your local build, or shade only the tiny api package. Either way, mark it soft:
# plugin.yml
softdepend: [EconGuard]You don't need depend: — the EconGuard.get() guard means a missing EconGuard is a no-op, not an error. Reporting is fire-and-forget: build the event, hand it to record(), done.
EconGuard · part of the eco suite (RoyalBank · RoyalAuctions · RoyalBazaar) · Source on GitHub
Getting started
Using it
Developers
Help