跨服设置
星月邮箱跨服只需要一个 MySQL(或 MariaDB)数据库,不需要在代理端(BungeeCord / Velocity)安装任何东西,也不需要 Redis。 所有子服连同一个数据库后:
- 在任何一个子服寄出的信,玩家在任何一个子服都能看到、领取;
- 玩家在线时,别的子服寄来的信几秒内就会提示;
- 每封信只能领一次,就算两个子服同时点领取也一样;
- 全服邮件每个玩家只会收到一封;
- 可以寄信给只在别的子服上线过的玩家。
设置步骤
- 建一个 MySQL 数据库,例如
starmail(字符集utf8mb4),准备好每个子服都连得到的账号。 - 每个子服的
plugins/StarMail/config.yml填同样的数据库,server-id填不同的名字:
database:
type: mysql
host: 192.168.1.10
port: 3306
database: starmail
username: starmail
password: '你的密码'
table-prefix: 'sm_' # 所有子服要一样
sync:
enabled: auto # 用 MySQL 时自动开启
server-id: 'lobby' # 每个子服不同:lobby、survival、skyblock…
interval-seconds: 3
- 重启每个子服(数据库与跨服设定
/sm reload不会生效)。控制台会显示:
[StarMail] 数据库已连接:MySQL 192.168.1.10:3306/starmail
[StarMail] 跨服已开启(子服 ID:lobby,每 3 秒检查一次其他子服的新邮件)
- 在每个子服输入
/sm version,确认都显示MySQL和正确的子服 ID。
不填也能跨服,但每次开服会自动生成一个随机名字(端口 + 随机字符),/sm log 里就看不出是哪个子服了。
table-prefix 不同的子服之间互相看不到邮件(它们用的是不同的表格)。同一个数据库里想放好几套互不相通的邮箱时,才需要故意设不同的前缀。
新邮件怎么跨服提示
| 情况 | 多久提示 |
|---|---|
| 收件人就在寄信的这个子服 | 立刻 |
| 收件人在别的子服 | 下一次轮询,最慢 interval-seconds(默认 3 秒) |
| 收件人离线 | 下次上线时的上线提示 |
每个子服每隔 interval-seconds 秒向数据库查询一次「有没有新的邮件、新的全服邮件」,只查编号比上次大的部分,查询非常轻。
查到寄给本服在线玩家的新邮件时,播放新邮件提示、更新 变量,玩家打开中的邮箱也会自动刷新。
调小 interval-seconds 提示更快,但每个子服的查询次数也更多;一般 2 ~ 5 秒都很合适。
每封信只领一次
领取附件时,插件先在数据库里执行一条「只有还没被领取时才标记为已领取」的更新,只有标记成功的子服才会发放附件:
- 玩家在 A 服打开邮箱后跑到 B 服领了附件,再回 A 服用旧画面点领取:提示「已经被领取过了(可能在其他子服)」,不会多给。
- 数据库会记下这封信是在哪个子服领取的,
/sm log的每条记录最后也会显示子服 ID。 - 删除、过期也是同样的做法,好几个子服同时清理过期邮件时,每封只会被处理一次(玩家寄出的过期附件也只会退回一次)。
全服邮件
全服邮件(@all、@all-existing、管理员写信的「全服」对象)在数据库里只存一份,在玩家上线时才复制一份进他的邮箱:
- 发出时,发信的子服上在线的玩家立刻收到;其他子服的在线玩家在下一次轮询(几秒内)收到。
- 离线的玩家在任何一个子服上线时收到。
- 每个玩家只会收到一封:数据库记录了谁已经收到哪一封,几个子服同时发放也不会重复。
/sm cancel <编号>在任何一个子服执行都对全部子服有效。
@online(管理员写信的「全部在线玩家」)只发给执行指令的那个子服上的在线玩家。想让所有子服的玩家都收到,请用 @all 或 @all-existing。
其他跨服行为
| 项目 | 跨服时 |
|---|---|
| 寄信给离线玩家 | 只要对方在任何一个连同一数据库的子服上线过(安装星月邮箱以后),就找得到 |
| 每日寄信次数 | 所有子服合计 |
| 寄信冷却 | 每个子服各自计算 |
邮件记录 /sm log | 所有子服的记录都在一起,每条显示子服 ID |
| 金币 / 点券附件 | 在领取的那个子服存入;那个子服要装 Vault 经济插件 / PlayerPoints。经济数据本身是否跨服由你的经济插件决定 |
| 领取指令 | 在领取的那个子服执行 |
插件用 MailDraft.key 寄的信 | key 存在共用的数据库里,任何子服用同一个 key 再寄都不会重复(StarAuction 星月市集跨服寄送就靠这个) |
templates.yml、messages.yml、菜单 | 每个子服各自一份,需要的话自己复制到每个子服 |
子服的 Minecraft 版本要一致
附件物品以 Paper 的完整物品数据保存。新版本服务器存的物品,旧版本服务器读不懂(旧版本存的物品,新版本可以读,会自动升级)。
如果子服版本不同,例如大厅是 1.21.11、生存服是 1.21.4:在大厅寄出的物品,玩家到生存服领取时会提示「邮件 #编号 的附件数据无法读取」, 附件不会发放,邮件也不会被标记为已领取——东西不会丢,玩家到 1.21.11 的子服(或更新的版本)就能领。
建议:
- 所有共用数据库的子服使用相同的 Minecraft 版本;
- 一定要混用时,在版本最旧的子服寄出附件(例如在旧版本子服执行
/sm send),这样每个子服都读得懂。 - 模板也一样:在游戏里存模板(
items-data)请在版本最旧的子服做。用新版本存的模板拿到旧版本子服发送时,物品读不出来,/sm send会停止并提示「模板 xxx 的物品数据无法读取」,不会寄出缺少物品的信;到版本最旧的子服重新保存这个模板即可。
从单服换成跨服
从 SQLite 换成 MySQL 不会自动搬移原本 data.db 里的邮件。换之前请让玩家先领完附件,或在旧服务器上保留一段时间。