diff options
author | nea <nea@nea.moe> | 2023-09-09 04:50:29 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-09-09 04:50:29 +0200 |
commit | c82c051704424763c20742b616228cfe636b9f65 (patch) | |
tree | d9400135aebefe40671d990218415443b842d033 /src/main/kotlin/moe/nea/firmament/features/texturepack | |
parent | dd974fcb79014452e6109dbeb008d5413819b73d (diff) | |
download | firmament-c82c051704424763c20742b616228cfe636b9f65.tar.gz firmament-c82c051704424763c20742b616228cfe636b9f65.tar.bz2 firmament-c82c051704424763c20742b616228cfe636b9f65.zip |
Add custom textures to placed skulls
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/features/texturepack')
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt b/src/main/kotlin/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt index b086811..66c0987 100644 --- a/src/main/kotlin/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt +++ b/src/main/kotlin/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt @@ -6,11 +6,21 @@ package moe.nea.firmament.features.texturepack +import com.mojang.authlib.GameProfile +import com.mojang.authlib.minecraft.MinecraftProfileTexture +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable +import net.minecraft.block.SkullBlock +import net.minecraft.client.MinecraftClient +import net.minecraft.client.render.RenderLayer +import net.minecraft.client.texture.PlayerSkinProvider import net.minecraft.client.util.ModelIdentifier +import net.minecraft.util.Identifier import moe.nea.firmament.events.CustomItemModelEvent import moe.nea.firmament.events.TickEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.util.IdentityCharacteristics +import moe.nea.firmament.util.item.decodeProfileTextureProperty import moe.nea.firmament.util.skyBlockId object CustomSkyBlockTextures : FirmamentFeature { @@ -19,6 +29,7 @@ object CustomSkyBlockTextures : FirmamentFeature { object TConfig : ManagedConfig(identifier) { val enabled by toggle("enabled") { true } + val skullsEnabled by toggle("skulls-enabled") { true } val cacheDuration by integer("cache-duration", 0, 20) { 1 } } @@ -32,8 +43,50 @@ object CustomSkyBlockTextures : FirmamentFeature { it.overrideModel = ModelIdentifier("firmskyblock", id.identifier.path, "inventory") } TickEvent.subscribe { - if (it.tickCount % TConfig.cacheDuration == 0) + if (it.tickCount % TConfig.cacheDuration == 0) { CustomItemModelEvent.clearCache() + skullTextureCache.clear() + } } } + + private val skullTextureCache = mutableMapOf<IdentityCharacteristics<GameProfile>, Any>() + private val sentinelPresentInvalid = Object() + + val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex() + fun getSkullId(profile: GameProfile): String? { + val textures = profile.properties.get(PlayerSkinProvider.TEXTURES) + val textureProperty = textures.singleOrNull() ?: return null + val texture = decodeProfileTextureProperty(textureProperty) ?: return null + val textureUrl = + texture.textures[MinecraftProfileTexture.Type.SKIN]?.url ?: return null + val mcUrlData = mcUrlRegex.matchEntire(textureUrl) ?: return null + return mcUrlData.groupValues[1] + } + + fun getSkullTexture(profile: GameProfile): Identifier? { + val id = getSkullId(profile) ?: return null + return Identifier("firmskyblock", "textures/placedskull/$id.png") + } + + fun modifySkullTexture( + type: SkullBlock.SkullType?, + profile: GameProfile?, + cir: CallbackInfoReturnable<RenderLayer> + ) { + if (type != SkullBlock.Type.PLAYER) return + if (!TConfig.skullsEnabled) return + if (profile == null) return + val ic = IdentityCharacteristics(profile) + + val n = skullTextureCache.getOrPut(ic) { + val id = getSkullTexture(profile) ?: return@getOrPut sentinelPresentInvalid + if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) { + return@getOrPut sentinelPresentInvalid + } + return@getOrPut id + } + if (n === sentinelPresentInvalid) return + cir.returnValue = RenderLayer.getEntityTranslucent(n as Identifier) + } } |