主题
HNEconomy 不只是玩家命令插件,它还提供了一层对外经济接口,给其他插件接入。
1. 当前 API 定位
当前对外接口的重点有四层:
- 基础经济接口:查余额、加钱、扣钱、设余额、转账
- 系统资金池接口:系统资金池入账 / 出账 / 三边结算
- 业务接入桥:商店、拍卖等业务桥接
- 统计与占位符桥:余额排行、手续费、系统资金池统计与 HNCore 占位符命名空间
也就是说,别的插件不应该直接改数据库,而应该通过 HNEconomy 的服务层完成经济操作。
2. 核心接口:EconomyApi
当前核心能力包括:
getBalance(...)has(...)deposit(...)withdraw(...)setBalance(...)transfer(...)playerPay(...)settleWithTreasury(...)treasuryDeposit(...)treasuryWithdraw(...)settleShop(...)isPayReceiveEnabled(...)setPayReceiveEnabled(...)getCurrency(...)getCurrencies()
设计重点
所有资金变更类接口都要求带:
TransactionContext
这不是多余参数,而是为了保证每次经济变更都具备:
- 变更类型
- 来源
- 原因
- 操作人
- 业务 ID
- 请求幂等标记
3. 统一入口:HNEconomyAPI
对外推荐通过:
java
HNEconomyAPI.getEconomyService()来拿经济服务。
当前还额外暴露了:
HNEconomyAPI.getCurrencyRegistry()HNEconomyAPI.getPayAnalyticsService()HNEconomyAPI.getShopEconomyBridge()HNEconomyAPI.getAuctionEconomyBridge()
这意味着:
- 业务插件可以直接读统计
- 也可以直接复用默认商店 / 拍卖接入实现
- 还可以直接读运行时货币注册表
4. 最小接入示例:给玩家加钱
java
import com.github.hnplugins.hneconomy.api.HNEconomyAPI;
import com.github.hnplugins.hneconomy.model.TransactionContext;
import com.github.hnplugins.hneconomy.constant.OperatorTypes;
UUID playerId = ...;
var economy = HNEconomyAPI.getEconomyService();
if (economy == null) {
return;
}
TransactionContext context = TransactionContext.builder()
.changeType("ACTIVITY_REWARD")
.reasonText("活动奖励")
.sourceType("EVENT")
.sourceId("spring-event")
.businessId("spring-event-2026-0001")
.operatorType(OperatorTypes.PLUGIN)
.operatorId("MY_PLUGIN")
.operatorName("MyPlugin")
.serverId("survival-1")
.build();
var result = economy.deposit(playerId, "gold", 100L, context);这里最重要的不是 deposit(...) 这一步本身,而是:
changeType写清楚sourceType/sourceId写清楚businessId尽量每笔业务唯一reasonText让运维看得懂
金额单位提醒
当前 API 金额参数是:
long- 按货币精度
scale存储的内部值
例如:
scale: 0的gold,100L就表示100scale: 2的货币里,1234L通常表示12.34
也就是说,API 层传的不是展示文本,而是内部账务单位。
如果你在接入时直接把玩家输入的 12.34 当成 12L 传进去,就会出现精度错误。
5. 为什么强制要求 TransactionContext
因为 HNEconomy 的核心原则是:
任何余额变化,都必须可追踪。
所以在集成层,最推荐的做法是:
- 明确写
changeType - 明确写
sourceType - 明确写
sourceId - 明确写
businessId - 明确写
reasonText
例如:
- 商店购买
- 拍卖结算
- 活动奖励
- 管理员补偿
都应该有自己清晰的上下文。
6. 商店接入接口
当前提供了:
ShopEconomyBridgeDefaultShopEconomyBridgeShopSettlementRequestShopSettlementResult
当前能力
- 扣玩家钱
- 给玩家发钱
- 向系统资金池结算
- 直接用
ShopSettlementRequest做统一结算
典型适用场景
- NPC 商店
- 服务器商城
- 活动商店
最小结算思路
如果你的商店只需要“买家扣款 + 系统资金池入账”,优先考虑直接走桥接接口, 而不是自己拆成多次调用。
示例:商店购买并结算到系统资金池
java
import com.github.hnplugins.hneconomy.api.HNEconomyAPI;
import com.github.hnplugins.hneconomy.api.business.BusinessContexts;
import com.github.hnplugins.hneconomy.api.business.ShopSettlementRequest;
UUID playerId = ...;
var bridge = HNEconomyAPI.getShopEconomyBridge();
if (bridge == null) {
return;
}
var context = BusinessContexts.shop(
"SHOP_BUY",
"NPC 商店购买",
"npc-shop",
"shop-order-0001",
"survival-1"
);
var result = bridge.settle(new ShopSettlementRequest(
playerId,
"gold",
100L,
true,
context
));这里的 settleToTreasury = true 表示:
- 玩家被扣款
- 对应金额进入系统资金池
- 整体作为一笔统一结算处理
7. 拍卖接入接口
当前提供了:
AuctionEconomyBridgeDefaultAuctionEconomyBridgeAuctionSettlementRequestAuctionSettlementResult
当前能力
- 买家付款
- 卖家到账
- 税费进入系统资金池
- 三边事务化结算
最关键的一点
拍卖接入的默认实现底层会走:
java
settleWithTreasury(...)这意味着:
- 不需要业务插件自己拆三步
- 不容易出现“买家扣了,卖家没到,税也没收”的半成功状态
示例:拍卖成交并收取税费
java
import com.github.hnplugins.hneconomy.api.HNEconomyAPI;
import com.github.hnplugins.hneconomy.api.business.AuctionSettlementRequest;
import com.github.hnplugins.hneconomy.api.business.BusinessContexts;
UUID buyerId = ...;
UUID sellerId = ...;
var bridge = HNEconomyAPI.getAuctionEconomyBridge();
if (bridge == null) {
return;
}
var context = BusinessContexts.auction(
"AUCTION_SETTLEMENT",
"拍卖成交",
"auction-house",
"auction-order-0001",
"survival-1"
);
var result = bridge.settle(new AuctionSettlementRequest(
buyerId,
sellerId,
"gold",
1000L,
50L,
context
));这个例子里:
- 买家总支出由桥接逻辑处理
- 卖家拿到成交金额
taxAmount对应的税费进入系统资金池- 整个流程在统一结算逻辑里完成
8. BusinessContexts 的作用
当前还提供了:
BusinessContexts.shop(...)BusinessContexts.auction(...)
这是为了统一构造:
sourceType = SHOPsourceType = AUCTION- 统一的插件操作人信息
避免不同业务插件各写各的来源字符串,最后数据库里出现一堆风格不一致的来源类型。
例子
java
var context = BusinessContexts.shop(
"SHOP_BUY",
"商店购买",
"npc-shop",
"shop-order-0001",
"survival-1"
);9. Vault 集成
当前 HNEconomy 可以注册为 Vault 的经济服务实现。
主要特点
- 默认映射主货币
- Vault 的入账 / 扣款同样落流水
- 来源会标记为
VAULT
当前定位
更适合:
- 给其他只认 Vault 的旧插件提供兼容层
而不是替代 HNEconomy 自己的多货币能力。
10. HNCore 占位符桥
当前 HNEconomy 提供的是 HNCore 占位符命名空间 economy。
这带来两种常见用法:
A. 在 HNCore 内部模板里使用
例如 GUI、消息模板:
text
{economy.balance_formatted}
{economy.currency_display}
{economy.pay_receive_text}B. 在 PlaceholderAPI 外部环境中使用
通过 HNCore 占位符桥访问:
text
%hncore_economy_<params>%例如:
text
%hncore_economy_balance_gold%
%hncore_economy_balance_formatted_point%
%hncore_economy_treasury_total_fee_gold%
%hncore_economy_top_balance_name_gold_1%最关键的一点是:
多货币占位符按
currencyId动态解析,不需要为每个货币单独新增一套固定占位符。
完整占位符清单、动态货币模板、回退规则与排查方法,见:
11. 集成时最推荐的原则
原则 1:不要自己写余额表
直接调 HNEconomy。
原则 2:不要绕过服务层直接改库
否则你会绕过:
- 事务
- 流水
- 系统资金池逻辑
- 幂等逻辑
- 统计与告警基础
原则 3:每笔业务都带 businessId
这样后续查账、补偿、回放都会轻松很多。
原则 4:来源字段尽量统一
能复用 BusinessContexts 的地方尽量复用, 不要让同一种业务在库里混出多套 sourceType 风格。
