附件系统
Assiah 支持五种附件类型,覆盖物品发放、信息传递、脚本执行、货币收发和物品库对接五大场景。
附件类型
| 类型 | 说明 | 领取行为 |
|---|---|---|
| 物品 (ITEM) | 背包中的实际物品 | 物品进入收件人背包 |
| 文本 (TEXT) | 纯文本信息 | 仅阅读,无需领取 |
| Kether (KETHER) | Kether 脚本 | 领取时自动执行脚本 |
| 货币 (CURRENCY) | 服务器货币(金币/点券等) | 领取时自动发放到账户 |
| 物品库物品 (SOURCE_ITEM) | 第三方物品库引用 | 领取时根据玩家上下文动态构建物品 |
物品附件
玩家在撰写邮件时,可以将手中持有的物品上传为附件。
操作方式:
- 打开撰写界面(
/assiah compose) - 将物品拿在手中
- 点击"上传物品"按钮
物品上传后会从玩家手中移除,存入草稿。如果删除草稿,物品附件会自动退回玩家背包。
领取物品附件
收件人领取物品附件时,插件会:
- 检查背包是否有足够空间(如果启用了
check-inventory-before-item-claim) - 将物品放入背包
- 如果背包满了,物品会掉落到玩家脚下
Kether 脚本附件
Kether 附件在领取时会自动执行指定的 Kether 脚本。适合用于:
- 发放金币、经验、点券
- 授予权限或称号
- 执行自定义逻辑
Kether 脚本附件仅允许管理员(assiah.admin 权限)或系统邮件使用。普通玩家无法添加 Kether 附件。
管理员编辑 Kether 附件
管理员在撰写界面中可以通过"编辑 Kether 脚本"按钮(命令方块图标)添加 Kether 脚本附件。点击后会打开笔与书编辑界面,输入 Kether 脚本内容。
相关 UI 文本配置:
ui:
compose:
kether-input-title: "Kether 脚本"
kether-attachment-display-name: "Kether 脚本"
如果 Kether 脚本执行失败且 rollback-on-kether-failure 为 true,整个领取操作会被回滚,包括已发放的物品附件。
Kether 自定义动作
Assiah 注册了 3 个 Kether 自定义动作,可以在其他插件的 Kether 脚本中使用:
| 动作 | 参数 | 说明 | 返回值 |
|---|---|---|---|
mail-send | <收件人> <标题> <正文> | 发送系统邮件 | Boolean |
mail-unread | [玩家] | 获取未读邮件数量(无参时取脚本 sender) | Long |
mail-has-unread | [玩家] | 是否有未读邮件 | Boolean |
使用示例:
# 检查玩家是否有未读邮件
if mail-has-unread then tell "&e你有未读邮件!"
# 发送系统邮件
mail-send "Steve" "活动奖励" "恭喜你获得了活动奖励!"
# 获取未读数量
set &count to mail-unread
tell "&e你有 {{&count}} 封未读邮件"
物品库附件
物品库附件(SOURCE_ITEM)允许管理员通过物品源 ID 引用第三方插件的物品作为邮件附件。与普通物品附件不同,物品库附件只存储引用 ID,在收件人领取时才根据玩家上下文动态构建实际物品。
同一封群发邮件,不同玩家领取时可以获得不同属性的物品。例如 MythicMobs 或 NeigeItems 的物品会根据领取玩家的等级、属性等动态生成。
物品库附件 vs 普通物品附件
| 对比项 | 物品附件 (ITEM) | 物品库附件 (SOURCE_ITEM) |
|---|---|---|
| 存储内容 | 完整 ItemStack 二进制 | 物品源引用 source:itemId |
| 构建时机 | 发送时序列化 | 领取时动态构建 |
| 玩家上下文 | 无(发送时快照) | 有(领取玩家作为构建参数) |
| 适用场景 | 玩家上传实体物品 | 管理员配置物品库物品 |
| 千人千面 | 不支持 | 支持 |
物品源引用格式
物品库附件使用 物品源:物品ID 的格式引用物品:
source:itemId → 指定物品源(如 "mm:legendary_sword")
itemId → 省略物品源时默认使用 minecraft 源(如 "diamond_sword")
示例:
| 引用格式 | 含义 |
|---|---|
mm:FireSword | MythicMobs 的 FireSword 物品 |
ni:starter_kit | NeigeItems 的 starter_kit 物品 |
ia:ruby_pickaxe | ItemsAdder 的 ruby_pickaxe 物品 |
diamond_sword | 原版钻石剑(默认 minecraft 源) |
mc:diamond | 原版钻石(显式指定 minecraft 源) |
mi:SWORD,FIRE_BLADE | MMOItems 的 SWORD 类型 FIRE_BLADE 物品 |
管理员添加物品库附件
管理员在撰写界面中可以通过"物品库物品"按钮(末影箱图标)添加物品库附件:
- 点击按钮后打开铁砧输入界面
- 输入物品源 ID(如
mm:legendary_sword) - 系统尝试预览构建结果
- 构建成功 → 展示预览物品图标,确认后添加为附件
- 构建失败 → 提示物品源不存在或物品 ID 无效
也可以通过管理员群发命令直接指定:
/assiah admin broadcast *:all "奖励邮件" "恭喜通关" --source-item mm:legendary_sword
/assiah admin broadcast *:all "新手礼包" "欢迎加入" --source-item ni:starter_kit --source-item diamond_sword
API 使用示例
通过 DSL 构建器添加物品库附件:
AssiahAPI.broadcastMail {
sender = SenderSnapshot.system()
recipients(allPlayers)
title = "通关奖励"
body = "恭喜你完成了挑战!"
attachment(SourceItemAttachment("mm:legendary_sword"))
attachment(SourceItemAttachment("ni:level_reward", amount = 3))
attachment(CurrencyAttachment("vault", 1000.0))
}
领取物品库附件
收件人领取物品库附件时,插件会:
- 解析物品源引用(
source:itemId) - 调用对应物品源的
build()方法,传入领取玩家作为上下文 - 设置物品数量
- 检查背包空间
- 将构建好的物品放入背包
如果物品源插件未加载或物品 ID 不存在,领取时会提示构建失败。请确保服务器安装了对应的物品源插件。
可用物品源列表
Assiah 内置了 25 个物品源适配器,会在启动时自动检测并注册已安装的物品源插件。
| 物品源 | 名称 | 别名 | 依赖插件 | 需要玩家上下文 | 说明 |
|---|---|---|---|---|---|
| 原版物品 | minecraft | mc, eq, equip | 无 | 否 | 原版材质名,如 mc:diamond_sword |
| Mod 物品 | mod | — | Mod 服务端 | 否 | Mod 物品 ID |
| MythicMobs | mythicmobs | mm, mythic | MythicMobs | 可选 | 传入玩家可生成等级相关物品 |
| ItemsAdder | itemsadder | ia | ItemsAdder | 否 | ItemsAdder 自定义物品 ID |
| NeigeItems | neigeitems | ni | NeigeItems | 可选 | 传入玩家可生成随机属性物品 |
| Oraxen | oraxen | ox | Oraxen | 否 | Oraxen 自定义物品 ID |
| Nexo | nexo | nx | Nexo | 否 | Nexo 自定义物品 ID |
| MMOItems | mmoitems | mi, mmo | MMOItems | 否 | 格式 mi:TYPE,ID(如 mi:SWORD,FIRE_BLADE) |
| Slimefun | slimefun | sf | Slimefun | 否 | Slimefun 物品 ID |
| HeadDatabase | headdatabase | hdb, head | HeadDatabase | 否 | 头颅数据库 ID |
| CraftEngine | craftengine | ce | CraftEngine | 可选 | 格式 ce:namespace:material |
| CustomFishing | customfishing | cf | CustomFishing | 是 | 需要玩家上下文构建 |
| Nova | nova | — | Nova | 否 | Nova 自定义物品 ID |
| Zaphkiel | zaphkiel | zap, zl | Zaphkiel | 可选 | Zaphkiel 物品 ID |
| Ratziel | ratziel | rz | Ratziel | 否 | Ratziel 物品 ID |
| Sertraline | sertraline | st | Sertraline | 可选 | Sertraline 物品 ID |
| SX-Item | sxitem | sx | SX-Item | 可选 | SX-Item 物品 ID |
| MagicGem | magicgem | mg | MagicGem | 否 | MagicGem 物品 ID |
| PxRpg | pxrpg | px | PxRpg | 是 | 需要玩家上下文,支持参数化 ID |
| AzureFlow | azureflow | af | AzureFlow | 可选 | AzureFlow 物品 ID |
| DragonArmourers | dragonarmourers | da, armourers | DragonArmourers | 否 | 龙之装甲师皮肤物品 |
| HMCCosmetics | hmccosmetics | hmc | HMCCosmetics | 否 | HMCCosmetics 装饰物品 |
| ExecutableItems | executableitems | ei | ExecutableItems | 可选 | ExecutableItems 物品 ID |
| EcoItems | ecoitems | — | EcoItems | 否 | Eco 系列物品 |
| EcoArmor | ecoarmor | — | EcoArmor | 否 | Eco 系列护甲 |
| EcoCrates | ecocrates | — | EcoCrates | 否 | Eco 系列箱子 |
| Talismans | talismans | — | Talismans | 否 | Eco 系列护符 |
| Reforges | reforges | — | Reforges | 否 | Eco 系列重铸 |
| StatTrackers | stattrackers | — | StatTrackers | 否 | Eco 系列统计追踪器 |
Assiah 启动时会自动检测服务器上已安装的插件,只注册对应插件已加载的物品源。未安装的插件对应的物品源会被跳过,不会报错。
物品源接口(ItemSource)是公开 API,第三方插件可以通过 ItemSourceRegistry.register() 注册自定义物品源。
附件数量限制
单封邮件的附件数量有上限,包括所有类型的附件。
limit:
max-attachment-count: 16
领取安全机制
Assiah 的领取流程内置了多重安全保护:
- 幂等锁:同一封邮件在领取过程中会加锁,防止并发重复领取导致物品复制
- 背包检查:领取前检查背包空间,空间不足时拒绝领取
- 失败重试:因网络等临时原因导致领取失败的邮件可以再次尝试
- Kether 回滚:脚本执行失败时可回滚整个领取操作
claim:
require-idempotent-lock: true
allow-retry-when-failed: true
check-inventory-before-item-claim: true
rollback-on-kether-failure: true
GUI 中的附件显示
不同类型的附件在 GUI 中使用不同的图标材质:
ui:
attachment-icon:
text: "PAPER" # 文本附件 → 纸
item: "CHEST" # 物品附件 → 箱子
kether: "COMMAND_BLOCK" # Kether 附件 → 命令方块
source-item: "ENDER_CHEST" # 物品库附件 → 末影箱