Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.

Commit a1c561c

Browse files
committed
process legacy (64x32) skins
1 parent 273f51f commit a1c561c

File tree

16 files changed

+221
-25
lines changed

16 files changed

+221
-25
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright © 2025 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.mixin.skins;
24+
25+
import net.minecraft.client.texture.NativeImage;
26+
import net.minecraft.client.texture.PlayerSkinTexture;
27+
import org.spongepowered.asm.mixin.Mixin;
28+
import org.spongepowered.asm.mixin.gen.Invoker;
29+
30+
@Mixin(PlayerSkinTexture.class)
31+
public interface PlayerSkinTextureAccessor {
32+
33+
@Invoker("remapTexture")
34+
static NativeImage invokeRemapTexture(NativeImage img) {
35+
throw new UnsupportedOperationException();
36+
}
37+
}

1.16_combat-6/src/main/java/io/github/axolotlclient/modules/auth/skin/SkinManager.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.github.axolotlclient.api.util.UUIDHelper;
3838
import io.github.axolotlclient.bridge.AxoMinecraftClient;
3939
import io.github.axolotlclient.bridge.util.AxoIdentifier;
40+
import io.github.axolotlclient.mixin.skins.PlayerSkinTextureAccessor;
4041
import io.github.axolotlclient.modules.auth.Account;
4142
import io.github.axolotlclient.util.ClientColors;
4243
import net.minecraft.client.MinecraftClient;
@@ -62,18 +63,27 @@ public Skin read(Path p) {
6263
byteBuffer.put(in);
6364
byteBuffer.rewind();
6465
try (var img = NativeImage.read(byteBuffer)) {
65-
if (img.getWidth() != 64 || img.getHeight() != 64) return null;
66-
slim = (ClientColors.ARGB.alpha(img.getPixelColor(47, 63)) == 0);
66+
int width = img.getWidth();
67+
int height = img.getHeight();
68+
if (width != 64) return null;
69+
if (height == 32) {
70+
var img2 = PlayerSkinTextureAccessor.invokeRemapTexture(img);
71+
img2.writeFile(p);
72+
slim = ClientColors.ARGB.alpha(img2.getPixelColor(47, 63)) == 0;
73+
} else if (height != 64) {
74+
return null;
75+
} else {
76+
slim = ClientColors.ARGB.alpha(img.getPixelColor(47, 63)) == 0;
77+
}
6778
}
6879
}
69-
return new Skin.Local(!slim, Hashing.sha512().hashUnencodedChars(p.toString()).toString(), p, sha256);
80+
return new Skin.Local(!slim, p, sha256);
7081
} catch (Exception e) {
7182
AxolotlClientCommon.getInstance().getLogger().warn("Failed to probe skin: ", e);
7283
}
7384
return null;
7485
}
7586

76-
7787
public CompletableFuture<AxoIdentifier> loadSkin(Skin skin) {
7888
var rl = AxoIdentifier.of(AxolotlClientCommon.MODID, "skins/" + skin.textureKey());
7989
if (loadedTextures.contains(rl)) {

1.16_combat-6/src/main/resources/axolotlclient.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"WorldRendererAccessor",
6363
"WorldRendererMixin",
6464
"api.JoinMulitplayerScreenMixin",
65+
"skins.PlayerSkinTextureAccessor",
6566
"translation.LanguageMixin"
6667
],
6768
"injectors": {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright © 2025 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.mixin.skins;
24+
25+
import com.mojang.blaze3d.texture.NativeImage;
26+
import net.minecraft.client.texture.PlayerSkinTexture;
27+
import org.spongepowered.asm.mixin.Mixin;
28+
import org.spongepowered.asm.mixin.gen.Invoker;
29+
30+
@Mixin(PlayerSkinTexture.class)
31+
public interface PlayerSkinTextureAccessor {
32+
33+
@Invoker("remapTexture")
34+
static NativeImage invokeRemapTexture(NativeImage img) {
35+
throw new UnsupportedOperationException();
36+
}
37+
}

1.20/src/main/java/io/github/axolotlclient/modules/auth/skin/SkinManager.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.github.axolotlclient.api.util.UUIDHelper;
3838
import io.github.axolotlclient.bridge.AxoMinecraftClient;
3939
import io.github.axolotlclient.bridge.util.AxoIdentifier;
40+
import io.github.axolotlclient.mixin.skins.PlayerSkinTextureAccessor;
4041
import io.github.axolotlclient.modules.auth.Account;
4142
import io.github.axolotlclient.util.ClientColors;
4243
import net.minecraft.client.MinecraftClient;
@@ -55,10 +56,20 @@ public Skin read(Path p) {
5556
var in = Files.readAllBytes(p);
5657
sha256 = Hashing.sha256().hashBytes(in).toString();
5758
try (var img = NativeImage.read(in)) {
58-
if (img.getWidth() != 64 || img.getHeight() != 64) return null;
59-
slim = (ClientColors.ARGB.alpha(img.getPixelColor(47, 63)) == 0);
59+
int width = img.getWidth();
60+
int height = img.getHeight();
61+
if (width != 64) return null;
62+
if (height == 32) {
63+
var img2 = PlayerSkinTextureAccessor.invokeRemapTexture(img);
64+
img2.writeFile(p);
65+
slim = ClientColors.ARGB.alpha(img2.getPixelColor(47, 63)) == 0;
66+
} else if (height != 64) {
67+
return null;
68+
} else {
69+
slim = ClientColors.ARGB.alpha(img.getPixelColor(47, 63)) == 0;
70+
}
6071
}
61-
return new Skin.Local(!slim, Hashing.sha512().hashUnencodedChars(p.toString()).toString(), p, sha256);
72+
return new Skin.Local(!slim, p, sha256);
6273
} catch (Exception e) {
6374
AxolotlClientCommon.getInstance().getLogger().warn("Failed to probe skin: ", e);
6475
}

1.20/src/main/resources/axolotlclient.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"WorldRendererAccessor",
6262
"WorldRendererMixin",
6363
"api.JoinMulitplayerScreenMixin",
64+
"skins.PlayerSkinTextureAccessor",
6465
"translation.TranslationStorageMixin"
6566
],
6667
"injectors": {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright © 2025 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.mixin.skins;
24+
25+
import com.mojang.blaze3d.platform.NativeImage;
26+
import net.minecraft.client.renderer.texture.SkinTextureDownloader;
27+
import org.spongepowered.asm.mixin.Mixin;
28+
import org.spongepowered.asm.mixin.gen.Invoker;
29+
30+
@Mixin(SkinTextureDownloader.class)
31+
public interface SkinTextureDownloaderAccessor {
32+
@Invoker("processLegacySkin")
33+
static NativeImage invokeProcessLegacySkin(NativeImage img, String url) {
34+
throw new UnsupportedOperationException();
35+
}
36+
}

1.21.7/src/main/java/io/github/axolotlclient/modules/auth/skin/SkinManager.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.github.axolotlclient.api.util.UUIDHelper;
3838
import io.github.axolotlclient.bridge.AxoMinecraftClient;
3939
import io.github.axolotlclient.bridge.util.AxoIdentifier;
40+
import io.github.axolotlclient.mixin.skins.SkinTextureDownloaderAccessor;
4041
import io.github.axolotlclient.modules.auth.Account;
4142
import io.github.axolotlclient.util.ClientColors;
4243
import net.minecraft.client.Minecraft;
@@ -55,10 +56,20 @@ public Skin read(Path p) {
5556
var in = Files.readAllBytes(p);
5657
sha256 = Hashing.sha256().hashBytes(in).toString();
5758
try (var img = NativeImage.read(in)) {
58-
if (img.getWidth() != 64 || img.getHeight() != 64) return null;
59-
slim = ClientColors.ARGB.alpha(img.getPixel(47, 63)) == 0;
59+
int width = img.getWidth();
60+
int height = img.getHeight();
61+
if (width != 64) return null;
62+
if (height == 32) {
63+
var img2 = SkinTextureDownloaderAccessor.invokeProcessLegacySkin(img, "local");
64+
img2.writeToFile(p);
65+
slim = ClientColors.ARGB.alpha(img2.getPixel(47, 63)) == 0;
66+
} else if (height != 64) {
67+
return null;
68+
} else {
69+
slim = ClientColors.ARGB.alpha(img.getPixel(47, 63)) == 0;
70+
}
6071
}
61-
return new Skin.Local(!slim, Hashing.sha512().hashUnencodedChars(p.toString()).toString(), p, sha256);
72+
return new Skin.Local(!slim, p, sha256);
6273
} catch (Exception e) {
6374
AxolotlClientCommon.getInstance().getLogger().warn("Failed to probe skin: ", e);
6475
}

1.21.7/src/main/resources/axolotlclient.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"WorldListWidgetEntryMixin",
6666
"WorldRendererMixin",
6767
"api.JoinMulitplayerScreenMixin",
68+
"skins.SkinTextureDownloaderAccessor",
6869
"translation.TranslationStorageMixin"
6970
],
7071
"injectors": {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright © 2025 moehreag <[email protected]> & Contributors
3+
*
4+
* This file is part of AxolotlClient.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*
20+
* For more information, see the LICENSE file.
21+
*/
22+
23+
package io.github.axolotlclient.mixin.skins;
24+
25+
import com.mojang.blaze3d.texture.NativeImage;
26+
import net.minecraft.client.texture.PlayerSkinTexture;
27+
import org.spongepowered.asm.mixin.Mixin;
28+
import org.spongepowered.asm.mixin.gen.Invoker;
29+
30+
@Mixin(PlayerSkinTexture.class)
31+
public interface PlayerSkinTextureAccessor {
32+
33+
@Invoker("remapTexture")
34+
static NativeImage invokeRemapTexture(NativeImage img) {
35+
throw new UnsupportedOperationException();
36+
}
37+
}

0 commit comments

Comments
 (0)