blessing-skin-plugins icon indicating copy to clipboard operation
blessing-skin-plugins copied to clipboard

[yggdrasil-api] [mojang-verification] uuid 表中数据不一致

Open yushijinhun opened this issue 1 year ago • 1 comments

问题描述

yggdrasil-api 和 mojang-verification 插件中的多个 bug 会导致 uuid 表中数据一致性被破坏。

1. 多个用户可以绑定同一个正版账户

mojang-verification 插件中,多个不同的用户可以绑定同一个正版账户,这在某些情况下会导致 uuid 表中同一个 uuid 对应多个 name。

重现方法:

  1. 登录用户 A,绑定正版账户,假设正版角色名称为 alex,此时会在用户 A 下创建一个名为 alex 的角色
  2. 将用户 A 中与正版账户同名的角色重命名,假设重命名为 bob
  3. 登录用户 B,绑定同一个正版账户,此时会在用户 B 下创建一个名为 alex 的角色
  4. alex 与 bob 的 uuid 相同

2. 更新 UUID 未考虑到改名情况

mojang-verification 插件中,更新 UUID 功能在正版角色重命名的情况下,会在 uuid 表中引入 name 不同而 uuid 相同的记录。

重现方法:

  1. 登录用户 A,绑定正版账户,假设正版角色名称为 alex
  2. 把正版角色重命名为 bob
  3. 使用更新 UUID 功能
  4. uuid 表中,alex 与 bob 的 uuid 相同

3. UUID 生成存在并发安全问题

yggdrasil-api 插件中,getUuidFromName 函数在为新角色生成 UUID 时,会出现并发安全问题,具体表现如下:

  • 如使用 version 3 算法,会在 uuid 表中插入多条 uuid 和 name 相同的记录
  • 如使用 version 4 算法,会在 uuid 表中插入多条 uuid 不同而 name 相同的记录

以上两种情况,受影响的记录的 id 一般都是相邻的。

4. 多次绑定正版账户导致 uuid 重复

mojang-verification 插件中,在同时多次调用 verifyCallback 时,会出现并发安全问题,进而使得 uuid 表中插入多条 uuid 和 name 相同的记录。

修复建议

  1. 为 uuid 表中的 uuid 字段、name 字段添加 unique 约束
  2. 移除 mojang-verification 插件中导入正版 uuid 的功能
  3. 对现有数据进行修正
    • 如果是 uuid 和 name 都相同的记录,保留一条即可
    • 如果是 uuid 不同,name 相同的记录,需要确定 hasJoined 接口返回的是哪个 uuid,保留这一 uuid 即可
    • 如果是 uuid 相同,name 不同的记录,需要先删除在 players 表中无对应 name 的记录(即此 name 目前未被使用,对应上面第 2 点),如仍有多条记录,则需要具体分析保留哪条记录,这将导致被删除记录的用户游戏数据丢失!

yushijinhun avatar Jul 16 '22 18:07 yushijinhun

我写了一个脚本 bs-uuid-migration 用来迁移并校验数据,并且会给 uuid 表添加 unique 约束,不过暂时还没有仔细测试。

yushijinhun avatar Jul 18 '22 14:07 yushijinhun