Files
MagicGem-Reforged/MIGRATION.md
T

12 KiB
Raw Blame History

MagicGem 迁移指南

本文说明如何从原版 MagicGem 或之前的 CMagicGem 重实现迁移到当前版本。迁移范围包括插件 JAR、配置文件、宝石、技能、GUI、语言文件,以及玩家物品中的宝石数据。

当前版本面向 Minecraft/Paper 1.21.x(包括 1.21.11),使用 Java 21。插件保留原插件的非授权功能,不实现网络授权或机器绑定。

迁移前的目录和插件身份

当前插件的身份仍然是 MagicGem:

name: MagicGem
main: pku.yim.magicgem.MagicGem

主命令是 /mgem,别名是 /cmgem 和 /cmg。新旧 JAR 不能同时运行,因为它们使用相同的插件名、数据目录和命令。

常见的数据目录有四种情况:

# 原版 MagicGem
plugins/
└─ MagicGem/

# 之前的 CMagicGem 重实现
plugins/
└─ CMagicGem/

# 两个目录同时存在
plugins/
├─ MagicGem/
└─ CMagicGem/

# 全新安装
plugins/

当前版本始终把 plugins/MagicGem 作为有效目录。plugins/CMagicGem 只作为旧数据来源导入。

第一次迁移前的准备

  1. 停止服务器,不能在服务器运行时替换 JAR 或修改插件数据。

  2. 备份整个服务器,至少包括以下内容:

    plugins/MagicGem/
    plugins/CMagicGem/
    world/
    world_nether/
    world_the_end/
    

    玩家背包、末影箱、容器和世界区块中的物品数据不在插件目录中,只备份插件目录不足以完整回滚。

  3. 移除旧版 MagicGem JAR 和旧版 CMagicGem JAR。

  4. 将当前版本 JAR 放入 plugins/。

  5. 保留 plugins/MagicGem 和 plugins/CMagicGem,不要在第一次启动前删除旧目录。

  6. 使用 Java 21 启动 Paper 1.21.x。

启动时的执行顺序

当前插件启动时会按照以下顺序工作:

  1. Paper 读取 plugin.yml,以 MagicGem 身份加载插件。
  2. onLoad() 预加载 NBT API。
  3. 执行旧目录导入器,检查 plugins/CMagicGem。
  4. 如果缺少默认 config.yml,创建当前版本的默认配置。
  5. 只为不存在的文件写入内置宝石、技能、GUI 和语言资源。
  6. 读取语言配置。
  7. 初始化宝石注册表、技能注册表、GUI、物品编解码器和软依赖集成。
  8. 执行完整 reload,读取配置并加载宝石、技能和 GUI。
  9. 注册 /mgem 命令和事件监听器。
  10. 输出集成状态和已加载宝石数量。

迁移必须发生在宝石和技能注册表加载之前。物品里保存的是宝石名或技能名,完整定义仍然来自 gems/*.yml 和 skills/*.yml。

情况一:只有原版 plugins/MagicGem

这种情况下不需要复制或重命名目录。当前版本会直接沿用:

plugins/MagicGem/config.yml
plugins/MagicGem/gems/*.yml
plugins/MagicGem/skills/*.yml
plugins/MagicGem/gui/*.yml
plugins/MagicGem/languages/*.yml

迁移器发现当前数据目录就是 plugins/MagicGem 后会跳过目录导入。已有配置不会被默认配置覆盖,已有资源文件也不会被内置资源覆盖。

旧配置中的以下写法都可以读取:

lang: zh_CN

或:

language: zh_CN

操作流程就是停止服务器、替换 JAR、保留 plugins/MagicGem、启动服务器。

情况二:只有 plugins/CMagicGem

如果不存在 plugins/MagicGem,但存在 plugins/CMagicGem,当前版本会创建 plugins/MagicGem,并导入以下内容:

CMagicGem/gems       → MagicGem/gems
CMagicGem/skills     → MagicGem/skills
CMagicGem/gui        → MagicGem/gui
CMagicGem/languages  → MagicGem/languages
CMagicGem/config.yml → MagicGem/config.yml

旧的 plugins/CMagicGem 源目录不会被删除,也不会被修改。

如果旧目录没有 config.yml,插件会在后续启动阶段创建当前版本默认配置。如果旧目录有配置而目标目录没有配置,插件会先创建默认配置,再用旧配置中的值覆盖对应默认项,同时保留新版本新增的配置项。

情况三:两个目录同时存在

当两个目录都存在时:

plugins/MagicGem/   # 有效目录,优先级高
plugins/CMagicGem/  # 旧目录,作为补充来源

迁移器只从 CMagicGem 补充目标目录中缺少的文件和配置项。MagicGem 中已经存在的内容优先保留。

例如旧文件是:

Shared:
  Name: Old Name
  Material: DIAMOND
  OldOnly: retained

当前目录中的文件是:

Shared:
  Name: Current Name
  Material: DIAMOND
  CurrentOnly: retained

合并后的目标文件是:

Shared:
  Name: Current Name
  Material: DIAMOND
  OldOnly: retained
  CurrentOnly: retained

也就是说,目标目录中的 Name 优先,旧目录独有的 OldOnly 会补入,目标目录独有的 CurrentOnly 也会保留。

文件合并规则

迁移器处理以下目录:

gems/
skills/
gui/
languages/

每个文件按照以下规则处理:

情况 行为
目标文件不存在 从 CMagicGem 复制到 MagicGem
YAML 文件同名且内容不同 递归合并,目标值优先
YAML 中只有旧目录存在的配置项 补入目标文件
YAML 中双方值不同 保留 MagicGem 值,记录冲突
非 YAML 文件内容相同 跳过
非 YAML 文件内容不同 保留目标文件,记录冲突
目标文件已存在 不直接覆盖

YAML 合并可以处理同一个文件中不同的宝石、技能或语言段落,而不是简单地按文件覆盖。

config.yml 合并规则

如果目标目录中没有 config.yml:

  1. 先生成当前版本默认配置。
  2. 导入旧配置中的字段。
  3. 旧配置存在的值覆盖默认值。
  4. 旧配置不存在的新字段继续保留默认值。

例如当前默认配置是:

language: zh_CN
workbench: true
backpack: false

旧配置是:

lang: en_US
backpack: true

最终结果会保留旧设置和新默认项,效果类似:

language: en_US
lang: en_US
workbench: true
backpack: true

如果目标配置已经存在,则目标配置优先,旧配置中目标没有的字段会补入:

# MagicGem/config.yml
language: zh_CN
backpack: false
# CMagicGem/config.yml
language: en_US
backpack: true
old-option: kept

最终目标配置会保持:

language: zh_CN
backpack: false
old-option: kept

冲突备份

发生冲突时,旧源文件会保存到:

plugins/MagicGem/migration-backup/CMagicGem/

例如:

plugins/CMagicGem/gems/Shared.yml

会备份为:

plugins/MagicGem/migration-backup/CMagicGem/gems/Shared.yml

配置文件冲突则会备份为:

plugins/MagicGem/migration-backup/CMagicGem/config.yml

控制台会列出冲突字段,并说明 MagicGem 的值被保留。旧源目录本身保持不变。

如果源文件和目标文件内容完全相同,不会被当作冲突,也不会产生额外备份。

迁移完成标记

完整迁移成功后会创建:

plugins/MagicGem/.migration-cmagicgem-v1.complete

该标记用于防止每次服务器启动都重复执行相同迁移。

如果第一次迁移过程中发生 IO 错误或 YAML 格式错误:

  • 不会写入完成标记;
  • 不会删除旧源目录;
  • 控制台会输出错误日志;
  • 下次启动会再次尝试迁移。

如果迁移完成后又修改了 plugins/CMagicGem,这些新修改不会自动再次导入,因为完成标记已经存在。需要重新导入时,应先停止服务器、备份当前 plugins/MagicGem、删除完成标记,再重新启动。

玩家物品的迁移方式

插件目录迁移和玩家物品迁移是两个独立过程。

当前版本不会在启动时遍历所有玩家背包并一次性重写全部物品,而是采用兼容读取和延迟迁移。物品在被识别、镶嵌、拆卸、强化或执行技能相关操作时,才会逐步写入当前格式。

物品可能包含以下数据格式:

当前 MagicGem PDC
旧 CMagicGem PDC
原版 MagicGem NBT
Lore 标识

当前版本会依次尝试读取:

magicgem:gem_name
cmagicgem:gem_name
MAGICGEM_NAME

如果允许使用 Lore 识别,还会把宝石 Lore 作为备用依据。

宝石名称

原版物品通常包含:

MAGICGEM_NAME

当前版本会使用这个名称去查找已经加载的宝石定义。识别成功后会写入当前 PDC:

magicgem:gem_name

原版 MAGICGEM_NAME 作为兼容字段继续保留。新创建的宝石也会同时写入当前标识和原版名称字段。

如果物品中的宝石名称存在,但 gems/*.yml 没有迁移或加载失败,插件无法恢复完整宝石定义。

镶嵌内容

原版镶嵌数据通常位于:

MAGICGEM_EMBED

它是一个包含宝石名称和数量的复合 NBT,例如:

{
  "AttributeGem": 2,
  "EnchantGem": 1
}

当前版本会按以下顺序读取:

  1. magicgem:embedded_gems;
  2. cmagicgem:embedded_gems;
  3. MAGICGEM_EMBED;
  4. 兼容旧格式的嵌套 NBT。

读取旧 NBT 后,物品在后续使用时会写入当前 PDC,同时继续写入兼容的 MAGICGEM_EMBED。执行镶嵌或拆卸时,这个受插件管理的字段会被重新整理;其他无关物品数据不会被主动删除。

技能列表

原版技能数据通常位于:

MAGICGEM_SKILL

当前版本会按以下顺序读取:

magicgem:skills
cmagicgem:skills
MAGICGEM_SKILL

读取成功后,技能名称会按当前格式保存,并继续写入兼容的 MAGICGEM_SKILL。技能是否能实际执行,还取决于对应的 skills/*.yml 是否已经加载。

启动后的检查

迁移成功时,控制台应出现类似日志:

Imported plugins/CMagicGem into plugins/MagicGem: X files copied, Y files merged, Z files with conflicts.

插件正常启用时,应出现类似日志:

MagicGem 已启用,命令 /mgem,加载 N 颗宝石。

建议执行以下检查:

/mgem view
/mgem get
/mgem embed
/mgem reload

还应实际测试:

  • 旧宝石是否可以识别;
  • 旧镶嵌装备是否显示正确;
  • 拆卸和重新镶嵌是否正常;
  • 技能是否能够触发;
  • GUI 是否可以打开;
  • 中文或英文语言是否正确;
  • Vault、PlayerPoints、PlaceholderAPI、MythicMobs 等软依赖是否正常;
  • 服务器重启后数据是否仍然存在。

如果日志显示宝石数量明显少于旧版本,应优先检查 plugins/MagicGem/gems/ 中的 YAML 是否完整,以及控制台是否有宝石解析错误。

回滚方式

最安全的回滚方式是停止服务器并恢复迁移前的完整备份:

  1. 停止服务器。
  2. 备份当前运行后的日志和数据,方便排查问题。
  3. 恢复旧版 MagicGem JAR。
  4. 恢复原来的 plugins/MagicGem。
  5. 必要时恢复玩家数据和世界备份。
  6. 启动服务器验证。

如果只有 plugins/CMagicGem,迁移器不会删除它,因此它可以继续作为旧配置来源。但是如果新版本运行期间已经改变了玩家物品或世界数据,仍然建议恢复完整服务器备份,而不是只恢复插件 JAR。

当前实现的注意事项

配置文件包含:

legacy-migration: true

但当前启动代码在读取配置前就调用目录导入器,因此这个开关目前不会阻止 CMagicGem 目录迁移。正常升级不需要修改它;如果以后需要支持关闭迁移,应将导入调用调整到配置加载之后,并显式检查该设置。

另外,目录识别使用的旧目录名是准确的:

plugins/CMagicGem

其他自定义目录名不会被自动扫描。需要使用其他目录名时,应在停服并备份后手动改名为 CMagicGem,或者手动合并文件。

迁移完成检查清单

  • 已停止服务器并备份插件、世界和玩家数据。
  • 已移除旧版 MagicGem/CMagicGem JAR。
  • 新 JAR 已放入 plugins/。
  • plugins/MagicGem 已保留。
  • plugins/CMagicGem 在确认迁移成功前已保留。
  • 控制台显示迁移结果或明确显示没有旧目录。
  • 没有未处理的 YAML 解析错误。
  • 宝石数量与预期一致。
  • 旧宝石、镶嵌装备和技能已实际测试。
  • GUI、语言和软依赖功能已测试。
  • 已保存冲突备份和迁移前备份。
  • 已重启服务器确认数据仍然正常。