SlimefunGuguProject / Slimefun4

Slimefun4 (粘液科技) 汉化版 | Slimefun modified version
GNU General Public License v3.0
246 stars 57 forks source link

正版玩家更改游戏名后,玩家数据库中的 p_name 列不会同步更新。 #905

Open XXY233 opened 4 weeks ago

XXY233 commented 4 weeks ago

问题描述

正版玩家更改游戏名后,profile.db 中的 p_name 不会同步更新。 这导致 /sf backpack 游戏名 这个命令会找不到对应的玩家。 我建议 p_name 可以在玩家更换游戏名后,及时更新,并且支持这个命令: /sf backpack uuid,这样玩家改名了但还没进过服务器,也可以顺利取到他的背包。

问题复现率

必现

复现步骤

服务端类型

Paper

Minecraft 版本

1.20.x

Slimefun 版本

image

其他插件信息

No response

补充信息

No response

StarWishsama commented 4 days ago

fe47722031d032b5c090c1de7b922958b54ee39b

XXY233 commented 4 days ago

如果检查 Bukkit.getOnlineMode(),在一些包含Bungeecord的服务器,或者是在线离线账号混合服务器上可能会出现问题。这些服务器一般都是将 Spigot 服务器的 online-mode 设置为 false,在 Bungeecord 或者通过 ProtocolLib 处理正版玩家。

StarWishsama commented 4 days ago

如果检查 Bukkit.getOnlineMode(),在一些包含Bungeecord的服务器,或者是在线离线账号混合服务器上可能会出现问题。这些服务器一般都是将 Spigot 服务器的 online-mode 设置为 false,在 Bungeecord 或者通过 ProtocolLib 处理正版玩家。

很有道理,但我觉得一开始我们就不应该硬匹配用户名的,应该 getPlayer -> UUID,算是坑了😿

XXY233 commented 1 day ago

🥲发现一个不太好的事情,如果数据库里有 2 个玩家重名,那么可能会查找到错误的玩家。 image

一般玩家重名的情况包括这 3 种:

  1. 服务器是在线模式,玩家 A 和 玩家 B 都是正版。玩家 A 更换游戏名之后从未加入过服务器,玩家 B 在此期间改名为玩家 A 的游戏名进入服务器。
  2. 服务器是混合模式,玩家 A 第一次加入服务器是离线模式,然后他输入了正版认证的指令 /premium 将自己游戏名标记为正版玩家,然后下一次加入服务器时,服务器会将他视为正版玩家,并产生一个正版 UUID 的玩家 A。
  3. 以上 2 种情况同时发生😵‍💫

可能的解决方案:

  1. 针对第一种情况,可以在玩家 B 加入服务器时,将玩家 A 的游戏名改为已过期。后续如果玩家 A 再次加入服务器,再更新为正确的游戏名。(还有一种补救方法,如果确定玩家 A 的 UUID 是 v4 的话,可以用 Mojang API 获取他的最新游戏名写入数据库)
  2. 针对第二种情况,如果数据库中查找到多个 UUID,则优先使用 UUID v4 的结果,忽略 UUID v3(离线模式)。
  3. 不管哪种情况,如果该游戏名的玩家在线,则应该优先使用在线玩家的 UUID,效果可能会好一点。
  4. 引入新命令: /sf backpack uuid
StarWishsama commented 1 day ago

这是一个设计问题,估计换成用 Bukkit.getPlayer 了,然后这个字段弃用。

XXY233 commented 1 day ago

👍️这样确实可以减少很多麻烦,但还是希望能够在未来加入 /sf backpack uuid 命令,这样玩家离线也可以获取到背包,在某些时刻也能提供有力的帮助😉