diff options
Diffstat (limited to 'src/main/java/de')
3 files changed, 89 insertions, 4 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index f2359265..6e702e7b 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -84,6 +84,7 @@ public class SkyblockerMod implements ClientModInitializer { Tips.init(); NEURepoManager.init(); ItemRepository.init(); + PlayerHeadHashCache.init(); HotbarSlotLock.init(); ItemTooltip.init(); WikiLookup.init(); diff --git a/src/main/java/de/hysky/skyblocker/mixin/PlayerSkinTextureMixin.java b/src/main/java/de/hysky/skyblocker/mixin/PlayerSkinTextureMixin.java index ea771c1e..1065bab0 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/PlayerSkinTextureMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/PlayerSkinTextureMixin.java @@ -1,19 +1,39 @@ package de.hysky.skyblocker.mixin; +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.callback.CallbackInfo; + +import com.llamalad7.mixinextras.injector.WrapWithCondition; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.item.PlayerHeadHashCache; import de.hysky.skyblocker.utils.Utils; import dev.cbyrne.betterinject.annotations.Inject; +import net.minecraft.client.texture.NativeImage; import net.minecraft.client.texture.PlayerSkinTexture; @Mixin(PlayerSkinTexture.class) public class PlayerSkinTextureMixin { + @Shadow + @Final + private String url; + + @Unique + private boolean isSkyblockSkinTexture; + + @Inject(method = "remapTexture", at = @At("HEAD")) + private void skyblocker$determineSkinSource() { + if (Utils.isOnSkyblock()) { + int skinHash = PlayerHeadHashCache.getSkinHash(this.url).hashCode(); + this.isSkyblockSkinTexture = PlayerHeadHashCache.contains(skinHash); + } + } - @Inject(method = "stripAlpha", at = @At("HEAD"), cancellable = true) - private static void skyblocker$dontStripAlphaValues(CallbackInfo ci) { - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.dontStripSkinAlphaValues) ci.cancel(); + @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) { + return !(SkyblockerConfigManager.get().general.dontStripSkinAlphaValues && this.isSkyblockSkinTexture); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java b/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java new file mode 100644 index 00000000..2a1688fc --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java @@ -0,0 +1,64 @@ +package de.hysky.skyblocker.skyblock.item; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.concurrent.CompletableFuture; + +import org.apache.commons.io.FilenameUtils; +import org.slf4j.Logger; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.logging.LogUtils; + +import de.hysky.skyblocker.utils.Http; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; + +public class PlayerHeadHashCache { + private static final Logger LOGGER = LogUtils.getLogger(); + private static final IntOpenHashSet CACHE = new IntOpenHashSet(); + + public static void init() { + CompletableFuture.runAsync(PlayerHeadHashCache::loadSkins); + } + + private static void loadSkins() { + try { + String response = Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/items"); + JsonArray items = JsonParser.parseString(response).getAsJsonObject().getAsJsonArray("items"); + + items.asList().stream() + .map(JsonElement::getAsJsonObject) + .filter(item -> item.get("material").getAsString().equals("SKULL_ITEM")) + .filter(item -> item.has("skin")) + .map(item -> Base64.getDecoder().decode(item.get("skin").getAsString())) + .map(String::new) + .map(profile -> JsonParser.parseString(profile).getAsJsonObject()) + .map(profile -> profile.getAsJsonObject("textures").getAsJsonObject("SKIN").get("url").getAsString()) + .map(PlayerHeadHashCache::getSkinHash) + .mapToInt(String::hashCode) + .forEach(CACHE::add); + + LOGGER.info("[Skyblocker Player Head Hash Cache] Successfully cached the hashes of all player head items!"); + } catch (Exception e) { + LOGGER.error("[Skyblocker Player Head Hash Cache] Failed to cache skin hashes!", e); + } + } + + //From MinecraftProfileTexture#getHash + public static String getSkinHash(String url) { + try { + return FilenameUtils.getBaseName(new URL(url).getPath()); + } catch (MalformedURLException e) { + LOGGER.error("[Skyblocker Player Head Hash Cache] Malformed Skin URL! URL: {}", url, e); + } + + return ""; + } + + public static boolean contains(int hash) { + return CACHE.contains(hash); + } +} |