64x 皮肤解析器(64x Skin Parser)
基本信息
| 属性 | 值 |
|---|---|
| 效果类型 | 客户端资源处理(PNG 解析) |
| 实现类 | roadhog360.simpleskinbackport.client.ImageBufferDownloadPlayerSkin |
| 替代对象 | net.minecraft.client.renderer.ImageBufferDownload |
| 触发来源 | 玩家皮肤纹理下载流程(SkinManager.func_152789_a) |
| 触发物品 | 玩家在线状态变更时自动下载的玩家皮肤 |
功能
替代原版 32x64 皮肤解析器,把老格式(32x64)玩家皮肤升级到 64x64,并把新格式(64x64)皮肤原样保留。解析完成后通过 Metadata.model = "slim" 自动判定 slim 手臂。
与原版 ImageBufferDownload 的差异
| 行为 | 原版 | 本实现 |
|---|---|---|
| 输出尺寸 | 32x64 | 64x64 |
| 32x64 老皮肤处理 | 直接拉伸 | 用 12 次 drawImage 复制源区域到 64x64 的对应位置 |
| 64x64 新皮肤处理 | 不识别 | 直接拷贝到 64x64 画布 |
| 头部/身体/装备区域 alpha 标记 | 一致 | 一致(同样的 setAreaOpaque/Transparent) |
老格式升级映射
源区域 (legacy 32x64) → 目标区域 (64x64) 用途
(4,16)-(8,20) → (24,48)-(20,52) 左臂顶层
(8,16)-(12,20) → (28,48)-(24,52) 左臂顶层(镜像)
(8,20)-(12,32) → (20,52)-(16,64) 左臂下半
(4,20)-(8,32) → (24,52)-(20,64) 左臂下半(镜像)
(0,20)-(4,32) → (28,52)-(24,64) 身体左半(顶层覆盖)
(12,20)-(16,32) → (32,52)-(28,64) 身体右半(顶层覆盖)
(44,16)-(48,20) → (40,48)-(36,48) 右臂顶层
(48,16)-(52,20) → (44,48)-(40,48) 右臂顶层(镜像)
(48,20)-(52,32) → (36,52)-(32,64) 右臂下半
(44,20)-(48,32) → (40,52)-(36,64) 右臂下半(镜像)
(40,20)-(44,32) → (44,52)-(40,64) 身体右半(顶层覆盖)
(52,20)-(56,32) → (48,52)-(44,64) 身体右半(顶层覆盖)
触发方式
触发 1:MixinAbstractClientPlayer
@Redirect(method = "getDownloadImageSkin",
at = @At(value = "NEW", target = "()Lnet/minecraft/client/renderer/ImageBufferDownload;"))
private static ImageBufferDownload use64xSkinParser() {
return new ImageBufferDownloadPlayerSkin(null, null);
}
每次 AbstractClientPlayer.getDownloadImageSkin() 调用时构造解析器(texture = null, callback = null 是临时 hack —— 注释说明:“Once I figure out how to inject where this is called in SkinManager.class I’ll do that instead.”)。
触发 2:MixinSkinManager
@WrapOperation(method = "func_152789_a",
at = @At(value = "NEW", target = "()Lnet/minecraft/client/renderer/ImageBufferDownload;"))
private ImageBufferDownload changeDownloadBufferManager(Operation<ImageBufferDownload> original,
@Local MinecraftProfileTexture p_152789_1_,
@Local MinecraftProfileTexture.Type p_152789_2_,
@Local SkinManager.SkinAvailableCallback p_152789_3_) {
if (Utils.isPlayer(p_152789_2_, p_152789_3_)) {
return new ImageBufferDownloadPlayerSkin(p_152789_1_, p_152789_3_); // 这里传 texture 和 callback
}
return original.call();
}
正式触发点:SkinManager.func_152789_a 中,MinecraftProfileTexture.Type.SKIN + callback 是 EntityPlayer 时替换。
解析完成后调用:Utils.setSlimFromMetadata
@Inject(method = "func_152789_a", at = @At(value = "TAIL", ...))
private void injectCallbackSkinCheck(MinecraftProfileTexture texture, ..., CallbackInfoReturnable<ResourceLocation> cir) {
if (Utils.isPlayer(type, callback) && callback instanceof IArmsState playerData) {
Utils.setSlimFromMetadata(texture, playerData);
}
}
Utils.setSlimFromMetadata:
public static void setSlimFromMetadata(MinecraftProfileTexture texture, IArmsState data) {
data.ssb$setSlim(Objects.equals(texture.getMetadata("model"), "slim"));
}
把 textures.SKIN.metadata.model = "slim" 映射为 IArmsState.ssb$setSlim(true)。
数值
| 数值 | 值 | 来源 |
|---|---|---|
| 目标画布尺寸 | 64x64 | imageWidth = imageHeight = 64 |
| BufferedImage 类型 | TYPE_INT_ARGB |
new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB) |
| 老格式尺寸判定 | buffImg.getHeight() == 32 |
仅当原图高 32 时升级 |
drawImage 调用数 |
12(老格式升级) | 循环体 6 行 × 2 镜像 |
| alpha 不透明区域 | (0,0)-(32,16)、(0,16)-(64,32)、(16,48)-(48,64) |
setAreaOpaque 调用 |
| alpha 透明区域 | (32,0)-(64,32)、(0,32)-(16,48)、(16,32)-(40,48)、(40,32)-(56,48)、(0,48)-(16,64)、(48,48)-(64,64) |
setAreaTransparent 调用 |
第三方 mod 集成
无直接依赖。ImageBufferDownloadPlayerSkin 是 Minecraft Forge net.minecraft.client.renderer.ImageBufferDownload 的纯客户端替代品。
相关条目
- Roadhog360 头颅 - 使用 64x 渲染管道的物品示例
- 1.8 皮肤模型系统 - 解析后用
MixinModelBiped渲染