- 版权类型
- 原创
- 插件中文名称
- 物质界
- 插件英文名称
- Assiah
- 原帖地址
- #
- 支持的核心(服务端)
- Spigot
- Paper
- Folia
- Purpur
- PufferFish
- Leaves
- 其他核心
- 语言支持
- 多语言
- 适配版本(Java)
- 1.21
- 1.20
- 1.19
- 1.18
- 1.17
- 1.16
- 1.15
- 1.14
- 1.13
- 1.12
[MD]
# 📬 Assiah
**全功能 Minecraft 邮箱系统插件**
## 文档链接: [https://plugin.hhhhhy.kim/docs/assiah/](https://plugin.hhhhhy.kim/docs/assiah/)
一封邮件,跨越服务器边界,送达每一位玩家。
---
## ✨ 为什么选择 Assiah
### 🔒 领取零风险
双层幂等锁(JVM 内存锁 + 数据库锁),分阶段执行物品 / 货币 / 脚本发放。即使服务器崩溃,重启后自动跳过已完成步骤,**绝不重复发放、绝不丢失附件**。
### 🌐 原生跨服
基于 Redis Pub/Sub 的跨服通知与玩家路由,邮件从 A 服发出、B 服实时收到提醒。不依赖 BungeeCord 插件通道,**Redis 不可用时自动降级,核心功能不受影响**。
### 🎨 YAML 驱动 GUI
6 套可视化菜单全部由 YAML 定义——布局、图标、条件、动作,改配置即改界面。支持子图标条件切换、Kether 脚本条件、模板占位符,**无需写一行代码即可自定义 UI**。
### 🧩 开发者友好
单例门面 `AssiahAPI`,全异步 `CompletableFuture` 返回值,Kotlin DSL 构建器 + Java 参数展开重载。9 个生命周期事件、3 个 Kether 动作,**5 分钟完成对接**。
### 💾 零配置存储
开箱即用 SQLite,一行配置切换 MySQL。10 张表自动建表、自动迁移,乐观锁保证并发安全,**不需要你懂数据库**。
### 💰 多经济体系
内置 Vault、PlayerPoints 桥接,支持通过 PlaceholderAPI + Kether 脚本对接任意自定义货币。**一个邮件可以同时携带物品、金币和脚本奖励**。
---
## 📮 功能一览
### 邮件收发
| 能力 | 说明 |
|:---|:---|
| **玩家互发** | 任意玩家之间发送邮件,支持标题、正文、多种附件 |
| **系统邮件** | 插件 / API 自动发送,绕过玩家黑名单与偏好限制 |
| **管理员邮件** | 管理员通过命令或 GUI 发送,可携带 Kether 脚本附件 |
| **群发广播** | 一键群发给在线 / 离线 / 全部玩家,单个失败不影响其他收件人 |
| **回复 & 转发** | 自动建立会话链,可配置是否复制物品 / Kether 附件 |
| **草稿箱** | 自动保存编辑中的邮件,支持手动保存、续写、发送 |
| **离线投递** | 收件人不在线时邮件持久化存储,上线后自动提醒 |
| **跨服投递** | BungeeCord / Velocity 网络中,邮件跨服实时送达 |
### 四种附件类型
```
📝 文本附件 — 纯文本说明,不可领取,仅展示
📦 物品附件 — 完整 ItemStack,保留 NBT / Lore / 附魔 / 自定义模型
💰 货币附件 — Vault / PlayerPoints / 自定义货币,领取时自动到账
⚡ Kether 附件 — 脚本逻辑,领取时主线程执行(仅管理员 / 系统可携带)
```
> 一封邮件可同时携带多种附件,最多 16 个。
### 邮件生命周期
```
创建 → 投递 → 未读 → 已读 → 已领取
↓ ↓
回收站 ← 归档
↓
永久删除(自动清理)
```
所有状态流转由状态机显式管理,每次变更递增版本号(乐观锁),杜绝并发冲突。
---
## 🖥️ 可视化界面
6 套 YAML 驱动的 GUI 菜单,开箱即用:
| 菜单 | 功能 |
|:---|:---|
| **邮箱主界面** | 邮件列表、分页翻页、文件夹切换、写信入口、批量操作 |
| **邮件详情** | 完整内容展示、附件列表、一键领取 / 删除 / 归档 / 回复 / 转发 |
| **写信界面** | 铁砧输入收件人和标题、书本编辑正文、手持物品上传、货币附件、Kether 编辑 |
| **草稿箱** | 草稿列表、续写、发送、删除 |
| **偏好设置** | 开关玩家邮件 / 系统邮件接收、白名单模式、黑名单管理 |
| **管理员面板** | 审查任意玩家邮箱概况、各文件夹统计 |
**自定义能力:**
- 布局字符映射——每个字符对应一个图标槽位,像画 ASCII 画一样设计界面
- 子图标条件切换——同一槽位根据 Kether 条件脚本展示不同图标
- 模板系统——动态渲染邮件摘要,支持 `{mail.title}`、`{mail.sender}`、`{mail.time}` 等占位符
- 40+ 种内置动作——`open-detail`、`claim`、`batch-delete`、`toggle-preference` 等,YAML 中直接引用
---
## ⌨️ 命令系统
主命令 `/assiah`(别名 `/mailbox`、`/ash`):
```
/assiah 打开邮箱主界面
/assiah inbox|sent|draft| 打开指定文件夹
trash|archive
/assiah compose [玩家名] 写新邮件(可预设收件人)
/assiah read <邮件ID> 查看邮件详情
/assiah claim <邮件ID> 领取邮件附件
/assiah reply <邮件ID> 回复邮件
/assiah forward <邮件ID> 转发邮件
/assiah preference 打开偏好设置
/assiah help 交互式帮助(悬浮提示 + 点击建议)
```
管理员命令(需 `assiah.admin` 权限):
```
/assiah reload 重载配置
/assiah admin inspect <玩家名> 审查玩家邮箱
/assiah admin send system <玩家名> 发送系统邮件
/assiah admin broadcast <目标> <标题> <正文>
群发(目标支持 *:on / *:off / *:all)
```
---
## 🔌 开发者 API
### 快速上手
```kotlin
// 引入 DSL 扩展
import kim.hhhhhy.assiah.api.AssiahAPI
import kim.hhhhhy.assiah.api.dsl.*
// 最简系统邮件 —— 一行搞定
AssiahAPI.sendSystemMail(playerUuid, "Steve", "欢迎回来", "你的每日奖励已到账")
// DSL 构建器 —— 复杂邮件也清晰
AssiahAPI.sendMail {
sender = SenderSnapshot.player(senderUuid, "Alex")
recipient = Recipient(targetUuid, "Steve")
title = "交易完成"
body = "你购买的钻石剑已发货,请查收附件。"
attachment(ItemAttachment(diamondSword))
attachment(CurrencyAttachment("vault", 100.0))
expireAt = System.currentTimeMillis() + 7 * 86400000L
}
// 查询邮箱 —— 过滤条件扁平化
AssiahAPI.queryMailbox(playerUuid) {
page = 1
folder = MailFolder.INBOX
unreadOnly = true
keywords = "奖励"
}
```
### Java 同样友好
```java
// 所有方法返回 CompletableFuture,Java 原生支持
AssiahAPI.INSTANCE.sendSystemMail(new SendMailRequest(
SenderSnapshot.system(),
new Recipient(targetUuid, "Steve", null, false, null),
"系统通知",
"服务器将于今晚维护",
Collections.emptyList(),
null, null, null, null,
RelationType.NONE, null, null, false
)).thenAccept(result -> {
if (result.getSuccess()) {
logger.info("邮件已发送: " + result.getMailId());
}
});
```
### 事件监听
```kotlin
@SubscribeEvent
fun onMailSend(event: MailSendEvent) {
// 发送前拦截 —— 唯一可取消的事件
if (event.request.title.contains("广告")) {
event.isCancelled = true
}
}
@SubscribeEvent
fun onMailClaim(event: MailClaimEvent) {
// 领取完成后触发
println("${event.ownerId} 领取了邮件 ${event.mailId}")
}
```
### Kether 脚本动作
```
mail-send "Steve" "标题" "正文" // 发送系统邮件
mail-unread // 获取当前玩家未读数
mail-has-unread // 是否有未读邮件(布尔值)
```
### API 完整能力
| 分类 | 方法 |
|:---|:---|
| 发送 | `sendMail` · `sendSystemMail` · `broadcastMail` |
| 查询 | `queryMailbox` · `getMail` · `getMailThread` · `getUnreadCount` |
| 操作 | `claimMail` · `deleteMail` · `restoreTrashMail` · `archiveMail` · `markAsRead` · `markAsUnread` |
| 草稿 | `saveDraft` · `getDraft` · `queryDrafts` · `deleteDraft` · `sendDraft` |
| 会话 | `replyMail` · `forwardMail` |
| 偏好 | `getPreference` · `updatePreference` |
| 黑名单 | `listBlockedPlayers` · `blockPlayer` · `unblockPlayer` |
| 批量 | `batchOperate`(已读 / 删除 / 归档 / 恢复 / 领取) |
| 管理 | `inspectMailbox` · `resendMail` · `moveMailFolder` |
---
## ⚙️ 配置与存储
### 存储架构
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ SQLite │ OR │ MySQL │ + │ Redis │
│ (默认) │ │ (多服共享) │ │ (可选增强) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────┬───────┘ │
▼ ▼
TabooLib PtcObject Pub/Sub 通知
10 张表自动管理 未读缓存 · 路由表
```
- **SQLite**:零配置,放入 plugins 文件夹即可运行
- **MySQL**:`config.yml` 中设置连接信息,适用于多服共享邮箱
- **Redis**:可选,启用后提供跨服实时通知、未读数缓存、玩家路由。不启用不影响任何核心功能
### 配置文件
| 文件 | 用途 | 亮点 |
|:---|:---|:---|
| `config.yml` | 全局开关、数据库、Redis | 一个 `mode` 字段切换 SQLite / MySQL |
| `mailbox.yml` | 邮箱行为、限制、过期策略 | 420+ 行,12 个配置节,每项都有中文注释和默认值 |
| `currency.yml` | 货币定义 | 内置 Vault + PlayerPoints,注释示例自定义货币 |
| `lang/zh_CN.yml` | 语言文件 | 410+ 行,覆盖所有消息、30+ 种错误码 |
| `ui/*.yml` | 6 套 GUI 布局 | 字符映射 + 模板 + 条件图标 + 动作绑定 |
### 可配置的行为限制
```yaml
# mailbox.yml 摘录
limit:
inbox-max: 500 # 收件箱容量
sent-max: 500 # 已发送容量
draft-max: 100 # 草稿上限
attachment-max: 16 # 单封邮件附件数
title-max-length: 64 # 标题字符数
body-max-length: 8000 # 正文字符数
broadcast-max: 200 # 单次群发上限
daily-send-limit: 50 # 每日发送上限
min-send-interval: 1000 # 最小发送间隔(毫秒)
```
---
## 🏗️ 技术架构
```
AssiahAPI(对外门面)
│
▼
MailFacadeService(业务聚合)
├── MailPublicService 发送 · 查询 · 领取 · 状态
├── DraftPublicService 草稿 CRUD · 发送
├── PreferencePublicService 偏好 · 黑名单
└── AdminPublicService 审查 · 重发 · 移动
│
▼
MailEntityStore(仓储层)
│
▼
PersistentContainer(TabooLib PtcObject)
│
┌───┴───┐
SQLite MySQL
```
**关键设计决策:**
- **门面模式** — `AssiahAPI` 是唯一对外入口,内部实现完全隔离
- **领域模型与存储模型分离** — `MailMapper` 负责双向转换,API 层不暴露数据库实体
- **状态机** — `MailStateMachine` + `MailStatusTransitionValidator` 管理所有状态流转
- **异步优先** — 数据库 I/O 全部异步,物品发放 / Kether 执行自动回到主线程
- **结构化结果** — 所有操作返回结果对象(`SendResult`、`ClaimResult` 等),失败时包含错误码和消息,禁止裸布尔值
### 依赖关系
| 依赖 | 类型 | 说明 |
|:---|:---|:---|
| **TabooLib 6** | 必选 | 框架核心,提供命令 / 配置 / UI / 数据库 / Kether |
| **Vault** | 可选 | 货币附件 —— 金币发放 |
| **PlayerPoints** | 可选 | 货币附件 —— 点券发放 |
| **PlaceholderAPI** | 可选 | 自定义货币余额查询 |
| **Redis** | 可选 | 跨服通知 / 缓存加速 |
---
**Assiah** — 让每一封邮件都值得信赖。
[/MD]