> ## Documentation Index
> Fetch the complete documentation index at: https://www.kitemc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# KiteMarket 市场 API 入门

> Java 11、MIT 的独立只读市场 SDK：查询、不可变 DTO、异步服务注册与安全成交通知。

<span id="市场-api-入门" />

`KiteMarket-API` 是独立的 Java 11／MIT SDK，不依赖闭源 `market-core`。它用于只读查询和成交后通知，不提供交易写入口。运行包、公开接口与示例的获取方式见[下载页](/kitemarket/download)。

<h2 id="引用-sdk">
  引用 SDK
</h2>

项目示例使用 GitHub Packages 的 Maven 坐标引用 SDK。GitHub Releases 的直接文件下载作为备用途径；两者提供同一套公开接口，不包含闭源交易核心。

<h3 id="github-packages">
  GitHub Packages
</h3>

| SDK | Maven 坐标 |
| - | - |
| 只读市场 API | `com.kitemc:kitemarket-api:1.0.0` |
| 界面 SDK | `com.kitemc:kitemarket-ui-api:1.0.0` |

仓库地址为 `https://maven.pkg.github.com/kitemc/KiteMarket`。对应正式版本发布后，由发行流程上传两个 SDK、sources、Javadoc 和 POM；引用前先确认[公开仓库](https://github.com/KiteMC/KiteMarket)的 Packages 列表已包含所需版本。下面是引用配置，不表示版本已经上传；运行插件、示例和语言／配置包继续从 GitHub Releases 获取。

GitHub 的 Maven／Gradle 仓库即使包是公开的，也要求下载认证。本地使用具有 `read:packages` 的 **personal access token (classic)**，用户名为你的 GitHub 用户名；只读下载不需要 `write:packages`。将用户名与 Token 放到用户级 `~/.gradle/gradle.properties`，不要写入项目或提交到 Git：

```properties theme={null}
gpr.user=YOUR_GITHUB_USERNAME
gpr.key=YOUR_CLASSIC_PAT_WITH_READ_PACKAGES
```

Gradle Kotlin DSL：

```kotlin theme={null}
repositories {
    maven("https://repo.papermc.io/repository/maven-public/")
    maven {
        name = "GitHubKiteMarket"
        url = uri("https://maven.pkg.github.com/kitemc/KiteMarket")
        credentials {
            username = providers.gradleProperty("gpr.user")
                .orElse(providers.environmentVariable("GITHUB_ACTOR")).orNull
            password = providers.gradleProperty("gpr.key")
                .orElse(providers.environmentVariable("GITHUB_TOKEN")).orNull
        }
        content {
            includeModule("com.kitemc", "kitemarket-api")
            includeModule("com.kitemc", "kitemarket-ui-api")
        }
    }
}
dependencies {
    compileOnly("com.kitemc:kitemarket-api:1.0.0")
    compileOnly("com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT")
}
tasks.withType<JavaCompile>().configureEach {
    options.release.set(11)
}
```

也可使用 `GITHUB_ACTOR`／`GITHUB_TOKEN` 环境变量提供同一组下载凭据。仍需保留项目原有的 Paper／Bukkit 编译依赖及其仓库。

Maven 项目的 `pom.xml` 增加以下仓库和依赖：

```xml theme={null}
<repositories>
  <repository>
    <id>github-kitemarket</id>
    <url>https://maven.pkg.github.com/kitemc/KiteMarket</url>
  </repository>
</repositories>
<dependencies>
  <dependency>
    <groupId>com.kitemc</groupId>
    <artifactId>kitemarket-api</artifactId>
    <version>1.0.0</version>
    <scope>provided</scope>
  </dependency>
</dependencies>
```

在用户级 `~/.m2/settings.xml` 配置同名服务器，凭据从环境变量读取；如果文件已存在，只合并 `server` 条目：

```xml theme={null}
<settings>
  <servers>
    <server>
      <id>github-kitemarket</id>
      <username>${env.GITHUB_ACTOR}</username>
      <password>${env.GITHUB_TOKEN}</password>
    </server>
  </servers>
</settings>
```

`401`／`403` 先检查 Token 类型、权限、有效期与用户名；`404` 还需检查坐标和该版本是否已发布。认证规则以 GitHub 的 [Gradle](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry)与 [Maven](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry)文档为准。

<h3 id="release-下载备用">
  Release 下载备用
</h3>

离线开发或无法使用 Packages 认证时，可从 [GitHub Releases](https://github.com/KiteMC/KiteMarket/releases)直接下载对应版本的 `KiteMarket-API-1.0.0.jar`，自行管理仅供编译的依赖。Release 文件下载不需要 Packages Token；公开仓库提供接口源码、Javadoc 与可运行示例。这里只是备用文件获取方式，不改变下述运行时约束。

`plugin.yml` 添加 `depend: [KiteMarket]`。若你的插件没有市场也能运行，可使用 `softdepend`，但仅在确认主插件存在后加载引用 API 的适配类，避免缺失类错误。

**不要打包、shade 或重定位 SDK**。运行时由 KiteMarket 提供唯一接口类，重复副本可能导致服务无法识别。SDK JAR 不是服务器插件。

<h2 id="等待服务-再异步查询">
  等待服务，再异步查询
</h2>

```java theme={null}
import com.kitemc.market.api.KiteMarketApi;

KiteMarketApi api = getServer().getServicesManager().load(KiteMarketApi.class);
if (api == null) return; // 数据库尚未就绪，等待 ServiceRegisterEvent。

api.orders(null, null, "", 0, 36).whenComplete((orders, failure) -> {
    if (!isEnabled()
        || getServer().getServicesManager().load(KiteMarketApi.class) != api) return;
    if (failure != null) {
        getLogger().warning("Market query unavailable");
        return;
    }
    orders.forEach(order -> getLogger().info(
        order.getId() + " " +
        order.getCurrency().display(order.getUnitPrice()).toPlainString()));
});
```

`depend` 只保证加载顺序，不保证数据库已连接。监听 `ServiceRegisterEvent` 后重新获取服务，并在卸载或替换时丢弃旧结果。可运行查询示例位于公开仓库 `examples/api-java`，包含延迟注册、失败处理和有容量限制的事件去重，不新增玩家命令。

查询返回 `CompletableFuture`。不能在主线程、Folia 区域线程或玩家线程 `get()`／`join()` 等待。回调不保证玩家调度上下文；更新 GUI、发送玩家信息或读取背包需另行正确调度。失败应显示暂不可用，不能伪装成零余额或空市场。

<h2 id="查询与结果">
  查询与结果
</h2>

| 方法 | 返回内容 |
| - | - |
| `networkId()` | 市场网络的持久化 UUID |
| `currencies()` | 币种 ID 与固定精度 |
| `orders(type, owner, search, offset, limit)` | 订单页；类型可空，owner 为空仅查开放订单，指定 owner 包含其终态订单 |
| `order(id)` | 指定订单；不存在时异常完成 |
| `wallets(player)` | 指定玩家的可用余额和冻结余额 |
| `assets(player)` | 可领取条目 ID、数量与物品摘要 |
| `history(player, offset, limit)` | 指定玩家的审计白名单摘要 |

分页要求 `offset >= 0`、`1 <= limit <= 100`，搜索最多256字符。历史按原审计行分页，未知内部类型投影为 `OTHER`，不泄露原始记录。

所有金额使用 `long` 最小货币单位。`CurrencyView.getPrecision() == 2` 时，`128` 表示 `1.28`；用 `currency.display(amount).toPlainString()` 格式化。时间为 Unix 毫秒，税率使用基点。

一口价 `SELL` 和收购 `BUY` 的 `getUnitPrice()` 是每件单价；拍卖 `AUCTION` 为整标起价。一口价允许部分购买，金额为单价×本次购买数量，计算时检查整数溢出，例如使用 `Math.multiplyExact`。

`OrderView.getMinimumPurchaseQuantity()` 为发布时固定的最低购买量，默认1，SELL可设为1至发布数量，其他类型为1。购买量须大于零、不超过剩余量，且至少为 `min(getMinimumPurchaseQuantity(), getRemaining())`；尾单不足最低量时必须一次买走全部剩余。原构造器保持可用并默认1，新重载在末尾增加 `long minimumPurchaseQuantity`。快照不替代最终校验，核心提交仍检查数量、资金和订单版本；历史与成交通知记录本次实际金额。

独立 DTO 在 `com.kitemc.market.api.model` 下：`CurrencyView`、`OrderView`、`WalletView`、`ClaimAssetView`、`HistoryEntry`、`TradeSummary`、`ItemSummary` 及枚举。字段和嵌套列表、集合、映射不可变。订单的可选样品摘要只含材质、名称、Lore、附魔与耐久，不能据此生成或领取资产。

接口不返回原始审计 JSON、序列化物品字节、精确样品指纹、许可证凭据、执行令牌或恢复证据。缺失历史金额保持 `null`，不猜成零；`RECORDED` 不表示外部副作用已经成功，`PENDING_REVIEW` 表示需要核对。物品匹配和交易提交由主插件处理，不属于公开查询接口。

<h2 id="成交后通知">
  成交后通知
</h2>

```java theme={null}
import com.kitemc.market.api.MarketCommittedEvent;
import com.kitemc.market.api.model.TradeSummary;
import org.bukkit.event.EventHandler;

@EventHandler
public void onTrade(MarketCommittedEvent event) {
    String deduplicationKey = event.getNetworkId() + ":" + event.getEventId();
    TradeSummary trade = event.getTrade();
    // 先按 deduplicationKey 去重；完整可运行示例提供有限近期缓存。
    getLogger().info(deduplicationKey + " " + event.getTopic()
        + " net=" + trade.getCurrency().display(trade.getNetIncome()).toPlainString());
}
```

`MarketCommittedEvent` 异步、不可取消，只报告已提交的 `BUY`、`SUPPLY`、`AUCTION_WON`。`getTrade()` 返回订单与操作 ID、类型、物品收取人、收益收取人、数量、币种、总额、税额和净收入；没有原始 `getPayload()`。

通知通过节点增量轮询触发，可能延迟或遗漏，启动前历史不自动补发，多个节点可能看到同一事件。按**网络 UUID＋事件 ID**去重；事件 ID 不保证连续。需要长期去重时自行持久化，不能把通知用作补发资金或物品的依据。重启后重新查询权威状态。

<h2 id="需要扩展玩家界面">
  需要扩展玩家界面？
</h2>

使用独立的 [UI SDK](/kitemarket/ui-development)，接收当前页面快照，并回传服务端登记的动作。最终权限、报价、背包重查和确认继续由 KiteMarket 完成。两个 SDK 均不能任意发币、扣物、绕过确认或执行远程交易写入。

自有配置主题和 Java IA 呈现器无需购买官方 DLC。第三方可自用、免费分发或独立销售；真实 IA 示例适配代码使用 Java 21，和两个 Java 11 SDK 的字节码边界分别看待。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.