开发者 API
GTCore 的公开 API 面向独立插件、附属插件和脚本。
它把物品库、属性插件、动作、GUI、变量、存储、性能计数等能力统一成稳定入口,业务插件只调用公开 SDK,不需要关心底层适配差异。
WARNING
只导入 com.rusbrook.gtcore.api 和 com.rusbrook.gtcore.sdk 下的公开类。
不要导入运行时内部包,也不要依赖混淆后的类名。
推荐依赖方式
插件编译时使用 GTCore SDK,运行时由服务器安装 GTCore。
plugin.yml:
yaml
softdepend:
- GTCore启动时检查:
kotlin
val gtcoreEnabled = server.pluginManager.isPluginEnabled("GTCore")
if (!gtcoreEnabled) {
logger.warning("未检测到 GTCore,相关兼容功能将关闭。")
}API 入口
kotlin
import com.rusbrook.gtcore.api.GTCore常用入口:
| 入口 | 用途 |
|---|---|
GTCore.items() | 创建、识别、发放、扣除统一物品 |
GTCore.matcher() | 匹配物品、权限、变量、NBT、PDC |
GTCore.actions() | 执行动作列表 |
GTCore.gui() | 打开 GUI、Dialog、输入框 |
GTCore.attributes() | 读取 AP、CA、SX 等属性 |
GTCore.economy() | 统一经济接口 |
GTCore.expressions() | 变量解析和条件计算 |
GTCore.storage() | 存储命名空间 |
GTCore.performance() | 性能计数和耗时统计 |
GTCore.clientGui() | PaiUI、DragonCore、ArcartX 等客户端 GUI |
统一物品
Kotlin:
kotlin
val item = GTCore.items().create("ni:starter_sword", player, 1)
if (item != null) {
player.inventory.addItem(item)
}Java:
java
ItemStack item = GTCore.INSTANCE.items().create("mm:BossKey", player, 1);
if (item != null) {
player.getInventory().addItem(item);
}Groovy:
groovy
def item = GTCore.items().create("ce:geartech:coin", player, 1)
if (item != null) {
player.inventory.addItem(item)
}支持常见写法:
text
DIAMOND
minecraft:diamond
ni:starter_sword
mm:BossKey
ia:namespace:item
oraxen:my_item
sx:my_item
mi:SWORD:MY_SWORD
ce:namespace:item识别手持物品
Kotlin:
kotlin
val identity = GTCore.items().identify(player.inventory.itemInMainHand)
player.sendMessage("来源: ${identity.provider}, ID: ${identity.id}")返回内容包括:
| 字段 | 说明 |
|---|---|
provider | 物品来源,例如 vanilla、neigeitems |
id | 物品库 ID |
material | Bukkit 材质 |
displayName | 显示名 |
customModelData | CMD |
tags | 可读取到的 PDC 字符串标签 |
匹配物品
Kotlin:
kotlin
val ok = GTCore.matcher().testItem(
player.inventory.itemInMainHand,
mapOf("item" to "ni:starter_sword"),
player
)使用 SDK Builder:
kotlin
import com.rusbrook.gtcore.sdk.GTMatcherRule
val rule = GTMatcherRule.builder()
.item("mm:BossKey")
.permission("dungeon.enter")
.condition("%player_level% >= 30")
.build()
val report = GTCore.matcher().matchContext(rule, player, player, player.inventory.itemInMainHand)
if (!report.success) {
player.sendMessage("条件不足: ${report.failed.joinToString()}")
}执行动作
Kotlin:
kotlin
GTCore.actions().execute(
sender = player,
player = player,
actions = listOf(
"[hasmoney] 1000",
"[money] take 1000",
"[item] ni:vip_box*1",
"[message] &a购买成功"
),
context = mapOf("shop" to "vip")
)Java:
java
GTCore.INSTANCE.actions().execute(
player,
player,
Arrays.asList(
"[hasmoney] 1000",
"[money] take 1000",
"[item] DIAMOND*3",
"[message] &a兑换成功"
),
Collections.emptyMap()
);动作会按顺序执行,检查类动作失败时会停止后续流程。
打开 GUI
Kotlin:
kotlin
import com.rusbrook.gtcore.sdk.GTGui
import com.rusbrook.gtcore.sdk.GTAction
val menu = GTGui.menu("&8测试菜单")
.rows(3)
.border(GTGui.material("GRAY_STAINED_GLASS_PANE", " "))
.button(
13,
GTGui.button(GTGui.material("DIAMOND", "&b领取钻石", listOf("&7点击领取")))
.actions(listOf(
GTAction.item("DIAMOND", 3),
GTAction.message("&a领取成功"),
GTAction.close()
))
.build()
)
.build()
GTCore.gui().openMenu(player, menu)Java:
java
GuiMenuSpec menu = GTGui.menu("&8测试菜单")
.rows(3)
.button(
13,
GTGui.button(GTGui.material("DIAMOND", "&b领取钻石", Arrays.asList("&7点击领取"), 1))
.actions(Arrays.asList(
GTAction.item("DIAMOND", 3),
GTAction.message("&a领取成功"),
GTAction.close()
))
.build()
)
.build();
GTCore.INSTANCE.gui().openMenu(player, menu, null);Dialog 确认
kotlin
val dialog = GTGui.dialog("&c确认购买")
.message(listOf("&7将扣除 1000 金币。", "&7确认后发放礼包。"))
.confirmItem(GTGui.material("LIME_WOOL", "&a确认"))
.cancelItem(GTGui.material("RED_WOOL", "&c取消"))
.confirmActions(listOf(
"[hasmoney] 1000",
"[money] take 1000",
"[item] ni:vip_box*1",
"[message] &a购买成功"
))
.cancelActions(listOf("[message] &7已取消"))
.build()
GTCore.gui().openDialog(player, dialog)高版本优先走 Dialog,低版本自动使用兼容方案。
属性读取
读取玩家属性:
kotlin
val dropRate = GTCore.attributes().value(player, "掉落概率") ?: 0.0
val crit = GTCore.attributes().value(player, "暴击率") ?: 0.0读取范围属性:
kotlin
val range = GTCore.attributes().range(player, "物理攻击力")
val avg = range?.average ?: 0.0刷新属性:
kotlin
GTCore.attributes().refresh(player)经济
kotlin
if (GTCore.economy().has(player, 1000.0)) {
val result = GTCore.economy().take(player, 1000.0, reason = "shop-buy")
if (result.success) {
player.sendMessage("购买成功,余额: ${result.balance}")
}
}表达式
解析文本:
kotlin
val text = GTCore.expressions().resolve(
"&a玩家 {player} 当前等级 %player_level%",
player,
player,
mapOf("player" to player.name)
)判断条件:
kotlin
val ok = GTCore.expressions().bool("%player_level% >= 30", player)计算数字:
kotlin
val amount = GTCore.expressions().number("100 + %player_level% * 2", player)存储命名空间
kotlin
val store = GTCore.storage().namespace("MyPlugin", "player-data", "auto")
val key = "points:${player.uniqueId}"
store.put(key, "100")
val points = store.get(key).join() ?: "0"需要 MySQL、Redis 等后端时,由 GTCore 统一加载和管理相关库,业务插件只使用命名空间。
性能计数
kotlin
GTCore.performance().increment("myplugin.exchange.success")
val start = System.nanoTime()
// do something
GTCore.performance().timing("myplugin.exchange.cost", System.nanoTime() - start)适合统计兑换次数、GUI 打开次数、数据库耗时、脚本耗时。
插件索引
kotlin
if (GTCore.plugins().isEnabled("MythicMobs")) {
player.sendMessage("MythicMobs 已加载")
}
val version = GTCore.plugins().version("NeigeItems")跨插件兼容时优先使用 GTCore.plugins(),避免每个插件重复写一套检测逻辑。
开发建议
- 只在主线程操作 Bukkit 实体、背包和 GUI。
- 数据库、网络、文件扫描放到异步,再回主线程发奖励或刷新 GUI。
- 物品库 ID、动作列表、条件表达式尽量配置化。
- 高频判断使用缓存,不要每次点击都全量扫描文件。
- 失败要给明确提示,例如缺物品、缺金币、缺权限。
