外观
地图画同步
基线:InvSync 2.5.33-BETA 的配置与地图实现。地图画同步默认关闭;本页描述代码行为,不代表已经完成跨版本、协议插件与地图墙场景的实机验收。上线前请先完成地图画验证。
同步的是什么
地图物品主要记录地图编号,像素保存在各子服的世界里。直接跨服携带同编号地图,可能显示空白或目标服上的另一幅画。
启用后,InvSync 保存地图的固定像素快照,按像素哈希生成全局编号(gid),同样的画面只存一份;物品上的 gid 随玩家数据跨服。目标服依赖共享像素记录和所选显示后端还原画面。
这不是动态地图同步。 不同步地形的持续更新、玩家光标或自定义渲染器的实时行为;ImageOnMap、ImageFrame 等图片插件自己的渲染器画面不在同步范围内。
所有相关子服一起开启
跨服双方都需要开启 map-sync.enabled 并使用同一套共享存储。只开一部分子服,未开启的子服仍可能显示空白或错误画面。1.12 的显示后端可按各服情况选择,但不能把协议兼容当作物品数据兼容。
配置与默认值
yaml
map-sync:
# 总开关,默认 false;可选 true/false,无单位
enabled: false
# 日常同步范围,默认 locked;可选 locked/all,无单位
mode: 'locked'
# 是否递归处理容器内地图,默认 true;最多两层嵌套
scan-containers: true
# 内存缓存画面数量,默认 512,范围 16–8192,每张约 16KB
cache-size: 512
# 仅供 1.12 子服使用,不改变 mode 的日常同步范围
legacy:
# 显示后端,默认 vanilla;可选 vanilla/virtual,无单位
render-mode: vanilla
# 停止新建原版地图的下一候选号阈值,默认 32000,范围 1–32767,无禁用值
vanilla-stop-id: 32000
# 后台重复故障警告间隔,默认 60 秒,范围 1–3600,无禁用值
warning-interval-seconds: 60| 配置 | 说明 |
|---|---|
mode: locked | 日常只上传已锁定地图;1.12 没有原版锁定功能,使用 vanilla 时只接收其它子服已有 gid 的画面,不上传本服普通地图 |
mode: all | 日常额外上传未锁定地图的当前快照;目标服显示固定画面,不随地形继续更新 |
scan-containers | 处理潜影盒、收纳袋中的地图,最多两层嵌套;不是任意深度容器遍历 |
cache-size | 内存中缓存的画面数量,超出范围按边界值处理 |
legacy.render-mode | 仅 1.12 使用;默认 vanilla,virtual 必须由管理员显式选择并重启 |
legacy.vanilla-stop-id | 只限制 InvSync 新建原版地图,不是地图编号扩容,也不会限制原版玩法或其它插件造图 |
legacy.warning-interval-seconds | 容量或后端等重复故障的后台限频提示间隔;不是超时后自动切换模式 |
未锁定地图会增加存储
all 模式下未锁定探索地图每次画面变化都可能产生新快照。除非确有需求,日常同步范围保持 locked。选择 virtual 另有旧图导入授权,见下文,不能据此认为 locked 会阻止该导入。
原版地图后端:vanilla(默认)
目标服优先复用已有且有效的「gid → 本地地图编号」映射;没有有效映射时,用共享像素新建本地原版地图并固定画面。成功写入并保存的原版地图不依赖虚拟发包显示,可用于展示框;停用插件后能否保持画面还取决于世界地图文件是否正确保存,应先重启验证。
1.12 的容量保护
1.12 的原版编号空间有限。默认 vanilla-stop-id: 32000 表示:下一个候选地图编号达到 32000 就停止 InvSync 的新分配,并非允许再分配编号 32000。计数为负、读取失败、候选号冲突或能力无法识别时也拒绝新建。
- 已有且有效的本服映射继续使用。
- 不因这项容量保护阻止玩家登录,也不删除地图物品;但尚未成功还原的画面可能空白或显示不正确。
- 后台默认每 60 秒限频警告,提示管理员评估 virtual,不会自动切换。
- 它不是 short 扩容,也不能阻止原版或其它插件继续消耗编号。不要通过改计数、删地图文件来规避保护。
1.12 虚拟后端:virtual
启用前提与代价
在 1.12 子服显式设置 map-sync.legacy.render-mode: virtual 并正常重启。当前旧版存储桥只识别 v1_12_R1,不承诺所有旧版本或混合端可用。
需要可用的协议后端:优先 PacketEvents,未启用或注册失败时尝试 ProtocolLib。没有可用后端时记录错误,不偷偷回退到 vanilla 分配地图。这个选择与玩家冻结配置 freeze 相互独立:使用 virtual 不要求把 freeze: def 改成 pe 或 plib。
virtual 为每条客户端连接分配临时显示编号,不为每幅画调用 createMap,也不把客户端会话编号写入数据库。它仍需要一个经过冲突和所有权检查的共享空白底图作为服务端物品载体。
代价是插件和协议后端必须持续运行,增加发包及缓存开销;每个客户端会话可容纳的地图数量有限,也可能与修改地图数据包的其它插件冲突。停用、卸载 virtual 或移除协议后端后,不保证这些画面仍可见。
显式切换也授权导入旧本服地图
选择 virtual 同时表示授权:把来源可确认的旧本服原版地图作为快照惰性导入。它不改变日常 locked / all 的含义,但这份导入授权不受日常 locked 阻止。
- 在遇到在线玩家物品、已加载区块中的箱子、展示框、掉落物等内容时逐批处理,不扫描整张世界的磁盘文件,也不会立即迁移全服离线数据。
- 先持久化像素并回读确认,再登记来源索引和转换物品;上传尚未成功时保留原物品,之后可重试。
- 原图文件和原编号来源索引保留,不清空世界旧图,也不回收原版地图计数。已有 gid 的地图沿用原 gid,不拿本服同号地图覆盖画面身份。
- 没有 gid、来源又不明的历史备份或跨服地图,不按本服碰巧相同的编号猜测画面。保留物品和来源标记,但无法因此恢复未知原画面。
- 导入的是当时的像素快照,不保留原图的动态地形、光标或渲染器行为;一轮扫描结束不代表整张世界已经迁移。
切回 vanilla
先备份、停止登录并正常停服,再修改配置重启。切回后仍需足够的原版地图编号容量;没有有效本服映射的画面可能需要新建原版地图。新产生的虚拟画不保证能无损转回原版地图,不能把切换后端当作无风险回退方案。
版本边界
| 环境 | 说明 |
|---|---|
| 1.14 及以上 | 实现使用原版锁定和本地像素写入路径;具体服务端、版本组合仍需测试 |
| 1.13 | 与 1.14 的地图 API 存在差异;不能仅凭部分编号兼容代码就认为已完整支持,不作完整支持承诺 |
| 1.12 / v1_12_R1 | vanilla 有编号容量保护;virtual 有专用存储桥与协议后端,按本页单独验证 |
| 更早版本、未识别的旧版分支或混合端 | 不从兼容层的旧物品判断推导为已支持,先确认具体环境 |
存储与备份
| 位置 | 用途 |
|---|---|
MySQL invsync_map_art / MongoDB map_art | 共享像素快照,按 gid 存储 |
plugins/InvSync/map-mapping.yml | vanilla 的「gid → 本地地图编号」映射 |
plugins/InvSync/legacy-map-sources.yml | virtual 的旧本服「原始地图编号 → 已确认 gid」来源索引,与主世界身份绑定 |
plugins/InvSync/legacy-map-backing.properties | virtual 共享底图所有权记录,包含世界、目录、编号与校验信息 |
主世界 data/map_<编号>.dat | 本服原版地图;virtual 的共享底图也在此目录,使用经过冲突检查的负编号,不使用 -1 |
这些本地文件由插件维护,不要手改或跨世界复制。备份时应一起保存共享库、世界和插件目录里的映射、来源及所有权文件。世界身份、底图校验失败或出现未完成的 .pending 所有权文件时,应保留现场并排查,不能靠删记录让插件重新接管未知地图。
失败边界
普通玩家数据同步处理背包(含装备、副手)、末影箱以及上述范围的嵌套容器;virtual 的旧图惰性导入另会接触已加载世界对象,但不是持续同步整张世界。
上传异步执行,玩家数据提交前最长等待 10 秒。失败或超时会记录异常档案,仍优先保存玩家物品,不保证目标服此时已有画面。缺少像素、容量、可用后端或来源信息时,应先保留日志和数据,再处理原因,不要反复删除映射重试。