rework: improve the accuracy of skin type determination

* Move code (icu.puqns67.skintypefix.mixin.accessor => icu.puqns67.skintypefix.accessor,
    icu.puqns67.skintypefix.mixin.patch => icu.puqns67.skintypefix.mixin).
* Fix the start and end points of the square may be in the wrong order.
* Update the format of log messages.
This commit is contained in:
Puqns67 2024-07-09 00:50:36 +08:00
parent 2b4b8237cc
commit 6ffbe6a4e4
Signed by: Puqns67
GPG Key ID: 9669DF042554F536
7 changed files with 27 additions and 28 deletions

View File

@ -1,4 +1,4 @@
package icu.puqns67.skintypefix.mixin.accessor;
package icu.puqns67.skintypefix.accessor;
import com.mojang.blaze3d.platform.NativeImage;

View File

@ -1,7 +1,7 @@
package icu.puqns67.skintypefix.mixin.patch;
package icu.puqns67.skintypefix.mixin;
import com.mojang.blaze3d.platform.NativeImage;
import icu.puqns67.skintypefix.mixin.accessor.HttpTextureAccessor;
import icu.puqns67.skintypefix.accessor.HttpTextureAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.texture.HttpTexture;
@ -22,7 +22,7 @@ public abstract class HttpTextureMixin extends SimpleTexture implements HttpText
private static Logger LOGGER;
@Unique
@Nullable
protected NativeImage image = null;
protected NativeImage skinTypeFix$image = null;
@Shadow
@Nullable
private CompletableFuture<?> future;
@ -46,27 +46,26 @@ public abstract class HttpTextureMixin extends SimpleTexture implements HttpText
}
@Unique
@Nullable
public NativeImage skinTypeFix$getImage() {
return this.image;
return this.skinTypeFix$image;
}
/**
* @author Puqns67
* @reason Overwrite the load() function to create another NativeImage at loading, using for check skin.
*/
@Nullable
@Overwrite
@Nullable
private NativeImage load(InputStream stream) {
try {
var result = NativeImage.read(stream);
if (this.processLegacySkin) {
result = this.processLegacySkin(result);
// If this.processLegacySkin is true, the image is the player's skin, so a backup needs to be created for check
if (result != null) {
this.image = new NativeImage(64, 64, true);
this.image.copyFrom(result);
}
this.skinTypeFix$image = new NativeImage(64, 64, true);
this.skinTypeFix$image.copyFrom(result);
result = this.processLegacySkin(result);
}
return result;
} catch (Exception e) {

View File

@ -1,4 +1,4 @@
package icu.puqns67.skintypefix.mixin.patch;
package icu.puqns67.skintypefix.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.authlib.SignatureState;
@ -6,7 +6,7 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import icu.puqns67.skintypefix.SkinTypeFix;
import icu.puqns67.skintypefix.mixin.accessor.HttpTextureAccessor;
import icu.puqns67.skintypefix.accessor.HttpTextureAccessor;
import icu.puqns67.skintypefix.util.Utils;
import icu.puqns67.skintypefix.util.image.Places;
import net.fabricmc.api.EnvType;
@ -75,14 +75,14 @@ public class SkinManagerMixin {
// Get image from PlayerSkinTexture
var skinImage = skinTexture.skinTypeFix$getImage();
if (skinImage == null) {
SkinTypeFix.LOGGER.warn("[SkinTypeFix] [{}] {GET_IMAGE} An error occurred while getting image!", uuid);
SkinTypeFix.LOGGER.warn("[SkinTypeFix] [{}] Unable to get image!", uuid);
return skinModelOrigin;
}
// Check skin type
var needFix = switch (skinModelOrigin) {
case SLIM -> !Places.PLAYER.isAllBlack(skinImage);
case WIDE -> Places.PLAYER.isAllBlack(skinImage);
case SLIM -> !Places.DIFF_PLAYER_SKIN.hasTransparent(skinImage);
case WIDE -> Places.DIFF_PLAYER_SKIN.hasTransparent(skinImage);
};
if (needFix) {

View File

@ -5,13 +5,13 @@ import com.mojang.blaze3d.platform.NativeImage;
import java.util.ArrayList;
public class Places {
public static final Places PLAYER = Places.forPlayer();
public static final Places DIFF_PLAYER_SKIN = Places.diffPlayerSkin();
private final ArrayList<Square> squares = new ArrayList<>();
public Places() {
}
public static Places forPlayer() {
public static Places diffPlayerSkin() {
var result = new Places();
result.add(50, 16, 51, 19);
result.add(50, 16, 51, 19);
@ -29,9 +29,9 @@ public class Places {
this.add(new Square(x1, y1, x2, y2));
}
public boolean isAllBlack(NativeImage image) {
public boolean hasTransparent(NativeImage image) {
for (var square : this.squares) {
if (!square.isAllBlack(image)) {
if (!square.hasTransparent(image)) {
return false;
}
}

View File

@ -9,7 +9,7 @@ public record Point(int x, int y) {
}
}
public boolean isBlack(NativeImage image) {
return image.getPixelRGBA(x, y) == 0xff000000;
public boolean isTransparent(NativeImage image) {
return image.getPixelRGBA(x, y) >>> 24 != 0xff;
}
}

View File

@ -6,8 +6,8 @@ import java.util.ArrayList;
public record Square(Point p1, Point p2) {
public Square {
// The point close to (0,0) is p1
if (p2.x() < p1.x() || p1.x() == p2.x() && p2.y() < p1.y()) {
// The point close to (0, 0) is p1, if the order is not correct then reverse them
if (p2.x() < p1.x() || (p2.x() == p1.x() && p2.y() < p1.y())) {
var tmp = p1;
p1 = p2;
p2 = tmp;
@ -28,9 +28,9 @@ public record Square(Point p1, Point p2) {
return result;
}
public boolean isAllBlack(NativeImage image) {
public boolean hasTransparent(NativeImage image) {
for (var point : this.points()) {
if (!point.isBlack(image)) {
if (!point.isTransparent(image)) {
return false;
}
}

View File

@ -1,5 +1,5 @@
{
"package": "icu.puqns67.skintypefix.mixin.patch",
"package": "icu.puqns67.skintypefix.mixin",
"client": [
"HttpTextureMixin",
"SkinManagerMixin"