aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/mixins/PlayerSkinTextureMixin.java
blob: 9b9691c542e17a35f58c4ddbed93dfdbd408b9f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package de.hysky.skyblocker.mixins;

import java.awt.Color;
import java.util.Set;

import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.skyblock.item.PlayerHeadHashCache;
import de.hysky.skyblocker.utils.Utils;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.PlayerSkinTexture;
import net.minecraft.util.math.ColorHelper;

@Mixin(PlayerSkinTexture.class)
public class PlayerSkinTextureMixin {
	@Unique
	private static final Set<String> STRIP_DE_FACTO_TRANSPARENT_PIXELS = Set.of(
			"4f3b91b6aa7124f30ed4ad1b2bb012a82985a33640555e18e792f96af8f58ec6", /*Titanium Necklace*/
			"49821410631186c6f3fbbae5f0ef5b947f475eb32027a8aad0a456512547c209", /*Titanium Cloak*/
			"4162303bcdd770aebe7fd19fa26371390a7515140358548084361b5056cdc4e6" /*Titanium Belt*/);
	@Unique
	private static final float BRIGHTNESS_THRESHOLD = 0.1f;

	@Shadow
	@Final
	private String url;

	@Inject(method = "remapTexture", at = @At("HEAD"))
	private void skyblocker$determineSkinSource(NativeImage image, CallbackInfoReturnable<NativeImage> cir, @Share("isSkyblockSkinTexture") LocalBooleanRef isSkyblockSkinTexture) {
		if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.dontStripSkinAlphaValues) {
			String skinTextureHash = PlayerHeadHashCache.getSkinHash(this.url);
			int skinHash = skinTextureHash.hashCode();
			isSkyblockSkinTexture.set(PlayerHeadHashCache.contains(skinHash));

			//Hypixel had the grand idea of using black pixels in place of actual transparent pixels on the titanium equipment so here we go!
			if (STRIP_DE_FACTO_TRANSPARENT_PIXELS.contains(skinTextureHash)) {
				stripDeFactoTransparentPixels(image);
			}
		}
	}

	@WrapWithCondition(method = "remapTexture", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/texture/PlayerSkinTexture;stripAlpha(Lnet/minecraft/client/texture/NativeImage;IIII)V"))
	private boolean skyblocker$dontStripAlphaValues(NativeImage image, int x1, int y1, int x2, int y2, @Share("isSkyblockSkinTexture") LocalBooleanRef isSkyblockSkinTexture) {
		return !isSkyblockSkinTexture.get();
	}

	@Unique
	private static void stripDeFactoTransparentPixels(NativeImage image) {
		int height = image.getHeight();
		int width = image.getWidth();

		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				int color = image.getColor(x, y);
				float[] hsb = Color.RGBtoHSB(ColorHelper.Abgr.getRed(color), ColorHelper.Abgr.getGreen(color), ColorHelper.Abgr.getBlue(color), null);

				//Work around "fake" transparent pixels - Thanks Hypixel I totally appreciate this!
				if (hsb[2] <= BRIGHTNESS_THRESHOLD) image.setColor(x, y, ColorHelper.Abgr.withAlpha(0x00, color & 0x00FFFFFF));
			}
		}
	}
}