CannaTaleEconomy

CannaTaleEconomy

服务器范围内的经济核心(SQLite)。

实用

CannaTaleEconomy

CannaTaleEconomy 是 CannaTale Hytale 服务器生态系统的经济核心。它提供基于 SQLite 的持久化余额系统、玩家和管理员命令、可配置的薪水系统(包括 VIP 等级)以及可供其他模组调用的公共 API


功能特点

核心

  • 使用 SQLite (economy.db) 持久化存储余额
  • 使用整数型货币 (Long),避免浮点数舍入问题
  • 通过数据库事务实现原子转账
  • /baltop 提供排行榜查询

命令

  • 玩家:/balance, /baltop, /pay, /paycheck
  • 管理员:/money set|give|take(单一权限节点)

薪水系统(VIP 覆盖)

  • 可配置的间隔时间和金额
  • VIP 权限节点:cannatale.economy.vip
  • VIP 玩家使用 /paycheck获得 paycheckAmountVip(忽略普通 paycheckAmount

公共 API 钩子

  • 其他模组可调用 EconomyApi 来读取/修改余额、转账、排行榜、格式化及薪水领取
  • 设计在服务器线程中调用(与命令/事件相同)

安装

  1. 构建插件 jar 文件(参见构建章节)。
  2. build/libs/ 中的非精简 jar 文件复制到你的服务器模组文件夹(例如:HytaleServer/mods/)。
  3. 启动服务器。
  4. 首次运行时,Economy 会在插件数据目录中生成其数据文件:
    • config.json
    • economy.db

配置(config.json

Economy 在首次运行时创建 config.json

当前配置项:

  • startingBalance (Long)
    新玩家的初始余额。

  • paycheckAmount (Long)
    默认薪水金额(非 VIP)。

  • paycheckAmountVip (Long)
    VIP 薪水金额。仅当玩家拥有 cannatale.economy.vip 权限时使用。

  • paycheckIntervalMinutes (Long)
    两个等级的共享薪水冷却时间(分钟)。

  • balTopLimit (Int)
    /baltop 显示的条目数量。

  • schemaVersion (Int)
    内部版本号,用于未来数据库迁移。

VIP 行为

如果玩家拥有 cannatale.economy.vip 权限,/paycheck 发放 paycheckAmountVip,忽略 paycheckAmount


权限

管理员(所有 /money 命令)

  • cannatale.economy.admin

VIP 薪水等级

  • cannatale.economy.vip

命令

根帮助

  • /economy
  • /ec(别名)

显示格式化的命令列表。


玩家命令

/balance

显示你的余额。

/balance [player]

显示另一名玩家的余额。

示例:

  • /balance
  • /balance Xion28080

/baltop

显示最高余额(默认前 10 名,可通过 balTopLimit 配置)。

示例:

  • /baltop

/pay <player> <amount>

向另一名玩家付款。

  • 金额必须 > 0
  • 发送者必须有足够的余额
  • 转账是原子操作

示例:

  • /pay Bob 250

/paycheck

领取你的薪水。

  • 受冷却时间限制:paycheckIntervalMinutes
  • VIP 玩家只获得 paycheckAmountVip

示例:

  • /paycheck

如果尚未就绪,你将看到一条消息,显示距离下次领取的剩余时间。


管理员命令(需要 cannatale.economy.admin

/money set <player> <amount>

设置玩家的余额。

/money give <player> <amount>

增加玩家的余额。

/money take <player> <amount>

减少玩家的余额(金额被扣除,而非转账)。

  • 最低为 0(不允许负余额)

示例:

  • /money set Bob 1000
  • /money give Bob 250
  • /money take Bob 500

在线玩家注意(ArgTypes.PLAYER_REF)

多个命令使用 ArgTypes.PLAYER_REF,这通常解析为在线玩家

  • /pay
  • /money set|give|take
  • /balance --player=<name>(如果参数解析为 PLAYER_REF)

如果需要离线支持(设置/检查不在线的玩家),Economy 可以通过配置文件存储或名称→UUID 缓存来扩展,以解析 UUID。


数据库

SQLite 文件:

  • economy.db

模式(概念性):

  • balances
    • uuid (TEXT PRIMARY KEY)
    • name (TEXT)
    • balance (INTEGER)
    • last_paycheck_claim_ms (INTEGER)

注意:

  • 金额存储为整数 (Long)
  • 转账使用事务以避免部分更新

公共 API 钩子(已声明)

API 位置

包:

  • org.omeganode.cannataleeconomy.api

主要接口:

  • EconomyApi

注册器:

  • EconomyApiRegistry

其他模组如何获取 API

import org.omeganode.cannataleeconomy.api.EconomyApiRegistry

val econ = EconomyApiRegistry.get() ?: return // Economy 未加载/未注册

EconomyApi — 方法和钩子(精确)

所有货币金额均为整数 Long 值。

大多数方法接受 nameForCreate,以便在账户缺失时按需创建。

package org.omeganode.cannataleeconomy.api

import org.omeganode.cannataleconomy.data.EconomyConfig
import org.omeganode.cannataleconomy.db.TopBalanceEntry
import org.omeganode.cannataleconomy.services.PaycheckService
import java.util.UUID

interface EconomyApi {
    fun getConfig(): EconomyConfig

    fun ensure(uuid: UUID, nameForCreate: String)

    /** 如果账户不存在则返回初始余额(不会创建账户)。 */
    fun getBalance(uuid: UUID): Long

    /** 返回余额,必要时创建账户。 */
    fun getBalance(uuid: UUID, nameForCreate: String): Long

    fun setBalance(uuid: UUID, nameForCreate: String, amount: Long)

    fun give(uuid: UUID, nameForCreate: String, amount: Long)

    /**
     * 从玩家余额中扣除最多 [amount](最低为 0)。
     * @return 扣除后的新余额。
     */
    fun take(uuid: UUID, nameForCreate: String, amount: Long): Long

    /**
     * 将 [amount] 从一名玩家转账给另一名玩家。
     * @return 成功返回 true,发送者余额不足或金额 <= 0 时返回 false。
     */
    fun transfer(fromUuid: UUID, fromName: String, toUuid: UUID, toName: String, amount: Long): Boolean

    fun top(limit: Int): List<TopBalanceEntry>

    /** 使用 Economy 所用的服务器区域规则格式化带逗号的数字。 */
    fun format(amount: Long): String

    /** 领取薪水。如果 isVip=true,仅使用 paycheckAmountVip。 */
    fun claimPaycheck(uuid: UUID, nameForCreate: String, isVip: Boolean): PaycheckService.ClaimResult
}

其他模组的 API 示例

读取余额(不创建账户)

val bal = econ.getBalance(playerUuid)

读取余额(缺失时创建账户)

val bal = econ.getBalance(playerUuid, playerName)

增加 / 扣除 / 设置

econ.give(playerUuid, playerName, 500)
val newBal = econ.take(playerUuid, playerName, 250)
econ.setBalance(playerUuid, playerName, 1000)

转账

val ok = econ.transfer(fromUuid, fromName, toUuid, toName, 200)

排行榜

val top = econ.top(10)

格式化

val formatted = econ.format(1234567) // "1,234,567"

领取薪水(VIP 感知)

val isVip = sender.hasPermission("cannatale.economy.vip")
val result = econ.claimPaycheck(playerUuid, playerName, isVip)

故障排除

运行时 SQLite 驱动程序错误

如果你看到: No suitable driver found for jdbc:sqlite:...

你很可能部署了错误的 jar 文件。

解决方法:

  • 部署 build/libs/ 中的非精简 jar 文件
  • 从服务器模组文件夹中移除旧的 Economy jar 文件
  • 重启服务器