Skip to content

可编译的 SealItems 接入示例

下面建立一个最小 Paper 插件,为玩家注册 /sealbridge enhancecraftsets 三个入口。示例只调用公开服务,不读取 Lore、PDC 或 SealItems 内部类。

1. 项目结构

text
sealitems-bridge/
├─ libs/sealitems-api-1.0.0.jar
├─ build.gradle.kts
├─ settings.gradle.kts
└─ src/main/
   ├─ kotlin/com/example/bridge/SealItemsBridgePlugin.kt
   └─ resources/plugin.yml

API JAR 必须与服务器上的 SealItems 主 JAR 来自同一次交付。

2. settings.gradle.kts

kotlin
rootProject.name = "sealitems-bridge"

3. build.gradle.kts

kotlin
plugins {
    kotlin("jvm") version "2.2.20"
}

repositories {
    mavenCentral()
    maven("https://repo.papermc.io/repository/maven-public/")
}

dependencies {
    compileOnly(files("libs/sealitems-api-1.0.0.jar"))
    compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
}

kotlin { jvmToolchain(21) }

如果团队固定了 Kotlin/Paper 版本,应使用团队基线;不要为了复制示例擅自升级生产依赖。

4. plugin.yml

yaml
name: SealItemsBridge
version: 1.0.0
main: com.example.bridge.SealItemsBridgePlugin
api-version: '1.21'
depend: [SealItems]
commands:
  sealbridge:
    description: 打开 SealItems 示例界面
    usage: /sealbridge <enhance|craft|sets>
permissions:
  sealitemsbridge.use:
    default: true

5. 插件主类

kotlin
package com.example.bridge

import cn.sealplugins.items.api.SealItemsApi
import cn.sealplugins.items.api.SealItemsCraftingApi
import cn.sealplugins.items.api.SealItemsSetsApi
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin

class SealItemsBridgePlugin : JavaPlugin() {
    override fun onCommand(
        sender: CommandSender,
        command: Command,
        label: String,
        args: Array<out String>,
    ): Boolean {
        val player = sender as? Player ?: run {
            sender.sendMessage("该命令只能由玩家执行")
            return true
        }
        if (!player.hasPermission("sealitemsbridge.use")) return true

        when (args.firstOrNull()?.lowercase()) {
            "enhance" -> {
                val api = server.servicesManager.load(SealItemsApi::class.java)
                if (api == null) {
                    player.sendMessage("SealItems API 尚未就绪")
                    return true
                }
                val result = api.openEnhancement(player.uniqueId)
                if (!result.opened) player.sendMessage(result.reason ?: "强化界面无法打开")
            }
            "craft" -> {
                val api = server.servicesManager.load(SealItemsCraftingApi::class.java)
                if (api == null) {
                    player.sendMessage("合成服务尚未就绪")
                    return true
                }
                val result = api.openCrafting(player.uniqueId)
                if (!result.opened) player.sendMessage(result.reason ?: "合成界面无法打开")
            }
            "sets" -> {
                val api = server.servicesManager.load(SealItemsSetsApi::class.java)
                if (api == null) {
                    player.sendMessage("套装服务尚未就绪")
                    return true
                }
                val result = api.openSets(player.uniqueId)
                if (!result.opened) player.sendMessage(result.reason ?: "套装界面无法打开")
            }
            else -> player.sendMessage("用法:/sealbridge <enhance|craft|sets>")
        }
        return true
    }
}

命令由 Paper 主线程调用,因此满足这些 GUI API 的线程要求。如果从异步任务、数据库回调或网络回调触发,必须先使用自己插件的调度器切回玩家合法执行上下文;不要让 API 替你调度。

6. 构建与安装

powershell
.\gradlew.bat clean build

只把 build/libs/sealitems-bridge-*.jar 放进测试服 plugins/。不要放入 libs/sealitems-api-1.0.0.jar。启动后确认加载顺序为 SealItems → SealItemsBridge,再逐个执行三个命令。

7. 必测失败场景

  • 玩家离线或玩法关闭时,返回值不是成功。
  • 从错误线程调用时,状态明确拒绝,不会悄悄调度。
  • SealItems 缺失时,硬依赖插件不会启用;改成软依赖后必须能安全关闭联动。
  • 服务器正常停止后,不再持有或调用旧 service 引用。