按用户名获取玩家的头:profile 组件如何工作,以及为什么头会变成空白
一个头存储的是皮肤快照,而不是实时链接。本文将介绍 profile 组件、为什么旧的头会显示错误的皮肤,以及 UUID 查询在其中的作用,客户端查到的皮肤会缓存起来,闲置五分钟以上才会重新去查询一次。
给出一个玩家的头听起来应该只需要一个参数。确实如此,但实际存储的内容并不是人们所期望的,而这解释了大多数与头相关的奇怪现象。
命令
/give @p player_head[profile="Notch"]
profile 组件取代了旧的 SkullOwner NBT。使用 {SkullOwner:"Notch"} 的片段属于 1.20.5 之前的版本,现在不起任何作用。
实际存储的内容
以 profile="Notch" 给出的头只存储名称。它是一个动态 profile——物品的提示框会说明这一点——每个玩家的客户端在绘制该头时会查询该名称并获取皮肤。只有当 profile 本身包含纹理时,头才会携带固定的快照:
"profile": {
"name": "Notch",
"id": [I; …],
"properties": [{ "name": "textures", "value": "<base64>" }]
}
两个后果:
- 基于名称的头会跟随玩家当前的皮肤。 绘制时会重新查询;客户端会保留已查询到的皮肤,直到它连续五分钟未被使用。只有携带
textures属性的头才会被冻结为某一个皮肤。 - 解析发生在查看者的机器上。 带有已烘焙
textures属性的头渲染时完全不需要查询。基于名称的头依赖于每个查看者的客户端能否连接到 Mojang,而与服务器的在线模式无关。
为什么头是空白的或显示 Steve
按可能性排序:
- 该名称未能为此客户端解析。 Mojang 的 API 无法访问,或者查询仍在进行中;在完成之前,头会显示默认皮肤。
- 该名称不存在。 对于已删除或从未注册的账户,Mojang 不返回任何内容。
- 仍在解析中。 查询在后台运行,因此头在首次进入视野后可能会短暂显示默认皮肤。
基于名称的头会在其缓存条目过期后自行重试。若要改为冻结皮肤,请在给出头时附带其 textures 属性——/fetchprofile name <name> 可以解析玩家并提供完整组件供复制,或者提供现成的头供给出。
自定义头使用纹理,而非名称
装饰性头——家具、食物、来自目录的生物头——没有所有者。它们只携带 properties 纹理值,其中包含指向纹理 URL 的 base64 数据块。这就是为什么它们可以作为一条长长的 give 命令分享,以及为什么当玩家改名时它们永远不会失效。
base64 解码后是一个小型 JSON,其中包含 textures.minecraft.net 上的 textures.SKIN.url。其中的其他内容对渲染没有任何影响。
UUID 格式
存在两种形式,它们并非在所有场景下都可以互换:
trimmed 069a79f444e94726a5befca90e38aaf5
dashed 069a79f4-44e9-4726-a5be-fca90e38aaf5
命令和 NBT 通常需要带连字符的形式或整数数组。Web API 通常返回去连字符的形式。两者之间的转换是机械性的——在第 8、12、16 和 20 个字符后插入连字符即可。
在玩家的头与用户名工具中,可以通过用户名给出头、浏览装饰性头目录,或在 UUID 格式之间进行转换。