Previous: ่ๆฌAPI.mdใยทใNext: ../05-ๅ่/ๆฏ่ฏญ่กจ.md Related: APIๆฆ่ง.md ยท ่ๆฌAPI.md ยท ../02-ๆไธปๆๅ/็ปๆตๅจไฝ.md ยท ../03-ๅค้จๆไปถๅฏนๆฅ/็ปๆตๆไปถ.md
๐ฐ Economy API โ
QCL uses EconomyBridge to flatten economy backends like Vault / ExcellentEconomy / PlayerPoints into a single unified set of calls. This page covers the com.qinhuai.corelib.economy package: all EconomyBridge methods, the EconomyProvider interface, EconomyTransactionResult and error codes, the differences between the three backends, selectProvider, parseMoneyRequirement, EconomyActionParser / EconomyGuiActions, plus call examples and best practices.
For the server-admin-facing GUI economy action syntax see ../02-ๆไธปๆๅ/็ปๆตๅจไฝ.md; for a detailed breakdown of backend integration differences see ../03-ๅค้จๆไปถๅฏนๆฅ/็ปๆตๆไปถ.md.
๐ EconomyBridge โ
The economy facade (a Kotlin object; from Java use INSTANCE). All amount methods accept an optional providerId / currencyId: if omitted, the default provider and default currency are used.
Lifecycle โ
| Method | Purpose |
|---|---|
init(plugin) | Initialize (called by QCL) |
reloadFromConfig() | Reload from config |
clear() | Clean up |
isAvailable(): Boolean | Whether an economy backend is available |
Query / Operations โ
| Method | Signature | Returns |
|---|---|---|
getBalance | getBalance(player: OfflinePlayer, providerId?, currencyId?) | Double |
has | has(player, amount, providerId?, currencyId?) | Boolean |
deposit | deposit(player, amount, providerId?, currencyId?) | EconomyTransactionResult |
withdraw | withdraw(player, amount, providerId?, currencyId?) | EconomyTransactionResult |
setBalance | setBalance(player, amount, providerId?, currencyId?) | EconomyTransactionResult |
Provider Selection / Info โ
| Method | Returns | Purpose |
|---|---|---|
selectProvider(providerId?, currencyId?) | EconomyProvider? | Select a specific provider (both omitted = default) |
getActiveProvider() | EconomyProvider? | The currently active provider |
availableProviderIds() | List<String> | All available provider ids |
getDefaultProviderId() | String | Default provider id |
getDefaultCurrencyId() | String | Default currency id |
Parsing / Diagnostics โ
| Method | Returns | Purpose |
|---|---|---|
parseMoneyRequirement(str) | MoneyRequirement | Parse a requirement string into a structure |
diagnose() | DiagnosticResult<List<BridgeStatus>> | Diagnose the status of each backend |
bridgeStatuses() | Status list | Detailed status of each backend |
๐ EconomyProvider Interface โ
Each economy backend implements an EconomyProvider:
interface EconomyProvider {
val id: String
fun isAvailable(): Boolean
fun getBalance(player, currencyId?): Double
fun has(player, amount, currencyId?): Boolean
fun deposit(player, amount, currencyId?): EconomyTransactionResult
fun withdraw(player, amount, currencyId?): EconomyTransactionResult
fun setBalance(player, amount, currencyId?): EconomyTransactionResult
}In general you do not need to implement a provider yourself (unless you are wiring up a new economy backend). Day-to-day integration goes through EconomyBridge.
๐งพ EconomyTransactionResult and Error Codes โ
EconomyTransactionResult(success, message?, code, suggestion, provider)Construction helpers:
EconomyTransactionResult.ok(provider)โโ success.EconomyTransactionResult.fail(message, code, suggestion, provider)โโ failure.result.toDiagnostic(source)โโ convert to a diagnostic object.
Common codes โ
| code | Meaning |
|---|---|
OK | Success |
CURRENCY_REQUIRED | The backend requires an explicit currency (e.g. ExcellentEconomy multi-currency), but no currencyId was passed |
INSUFFICIENT_FUNDS | Insufficient balance |
NO_PROVIDER | No economy backend available |
๐ฆ Differences Between the Three Backends โ
| Backend | Currency | Offline support | Key points |
|---|---|---|---|
| Vault | Single currency | โ Supports offline | No currencyId needed |
| ExcellentEconomy (EE) | Multi-currency | โ Online only | Must specify currencyId, otherwise reports CURRENCY_REQUIRED; offline players cannot be operated on |
| PlayerPoints | Points | โ Supports offline | Integer points; amounts are processed as integers |
See ../03-ๅค้จๆไปถๅฏนๆฅ/็ปๆตๆไปถ.md for details.
๐งฎ parseMoneyRequirement โ
Parses a requirement string into a MoneyRequirement(providerId, currencyId, operator, amount):
val req = EconomyBridge.parseMoneyRequirement(">=100")
// operator=">=", amount=100.0, provider/currency use defaults
val req2 = EconomyBridge.parseMoneyRequirement("excellenteconomy:gold:>=50")
// providerId="excellenteconomy", currencyId="gold", operator=">=", amount=50.0Syntax: [provider:][currency:]<operator><amount>. Used for "condition requires the player to have a certain amount of money" type checks.
๐ EconomyActionParser / EconomyGuiActions โ
EconomyActionParser โ
EconomyActionParser.parse(value) โ EconomyActionSpec(amount, providerId?, currencyId?, failMessage?), parses the value string in a GUI action into a structure (for the value syntax see ../02-ๆไธปๆๅ/็ปๆตๅจไฝ.md).
val spec = EconomyActionParser.parse("excellenteconomy:gold:500")
// amount=500, providerId="excellenteconomy", currencyId="gold"EconomyGuiActions โ
The economy executor for GUI click actions:
| Method | Corresponding action |
|---|---|
giveMoney | give_money |
takeMoney | take_money (checks balance first; does not deduct if insufficient) |
setMoney | set_money |
๐งช Call Examples โ
Query balance / check โ
val bal = EconomyBridge.getBalance(player)
if (EconomyBridge.has(player, 100.0)) {
// has at least 100
}double bal = EconomyBridge.INSTANCE.getBalance(player, null, null);
boolean ok = EconomyBridge.INSTANCE.has(player, 100.0, null, null);Withdraw (handling insufficient balance) โ
val r = EconomyBridge.withdraw(player, 100.0)
when {
r.success -> player.sendMessage("ๆฃๆฌพๆๅ")
r.code == "INSUFFICIENT_FUNDS" -> player.sendMessage("ไฝ้ขไธ่ถณ๏ผ${r.message}")
r.code == "NO_PROVIDER" -> logger.warning("ๆฒกๆๅฏ็จ็ปๆตๅ็ซฏ")
else -> player.sendMessage("ไบคๆๅคฑ่ดฅ๏ผ${r.message}๏ผ${r.suggestion}๏ผ")
}Deposit / set balance โ
EconomyBridge.deposit(player, 50.0)
EconomyBridge.setBalance(player, 0.0)Handling CURRENCY_REQUIRED (multi-currency backend) โ
var r = EconomyBridge.withdraw(player, 50.0) // no currency specified
if (r.code == "CURRENCY_REQUIRED") {
// multi-currency backends like EE must specify currencyId and retry
r = EconomyBridge.withdraw(player, 50.0, "excellenteconomy", "gold")
}Specifying provider / currency โ
val provider = EconomyBridge.selectProvider("excellenteconomy", "gold")
if (provider != null && provider.isAvailable()) {
provider.withdraw(player, 50.0, "gold")
}โ Best Practices โ
- Always check the returned
code, don't just look atsuccessโCURRENCY_REQUIRED/NO_PROVIDERneed to be handled differently. - Use
withdrawto deduct; it already checks the balance internally; don'tgetBalanceyourself and then deduct (there's a race condition). - For multi-currency backends (EE) always pass
currencyId, otherwiseCURRENCY_REQUIRED; and you can only operate on online players. - PlayerPoints uses integer points; passing a decimal will be processed as an integer, so keep this in mind when designing reward amounts.
- At startup, use
isAvailable()/diagnose()to confirm the backend is ready and give the server admin a clear error. - Use
result.messagefor prompts shown to players, andresult.code+result.suggestionfor pinpointing issues in logs.
๐ Further Reading โ
- ../02-ๆไธปๆๅ/็ปๆตๅจไฝ.md โโ the value syntax for
give_money/take_money/set_moneyin GUIs. - ../03-ๅค้จๆไปถๅฏนๆฅ/็ปๆตๆไปถ.md โโ integration details and differences for Vault / EE / PlayerPoints.
- ่ๆฌAPI.md โโ
qcl.economyHas/Withdraw/Depositin scripts. - ../05-ๅ่/ๆฏ่ฏญ่กจ.md โโ quick term reference.