mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 02:45:13 -04:00
verify skin size
This commit is contained in:
parent
803cdcc552
commit
acb3bd3b02
@ -58,6 +58,9 @@ class RGBA8Buffer(
|
||||
|
||||
override fun getRGBA(x: Int, y: Int): Int {
|
||||
val stride = stride(x, y)
|
||||
if (stride > data.capacity()) {
|
||||
throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size")
|
||||
}
|
||||
return (this[stride + 0] shl 24) or (this[stride + 1] shl 16) or (this[stride + 2] shl 8) or (this[stride + 3] shl 0)
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,9 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.MipmapTextureData
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.readTexture
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@ -70,7 +73,14 @@ abstract class DynamicTextureArray(
|
||||
}
|
||||
|
||||
private fun DynamicTexture.load(index: Int, creator: () -> TextureBuffer) {
|
||||
val buffer = creator.invoke()
|
||||
val buffer = try {
|
||||
creator.invoke()
|
||||
} catch (error: Throwable) {
|
||||
Log.log(LogMessageType.RENDERING, LogLevels.WARN) { "Could not load dynamic texture (index=$index, identifier=${this.identifier}): $error" }
|
||||
error.printStackTrace()
|
||||
this.state = DynamicTextureState.ERROR
|
||||
return
|
||||
}
|
||||
|
||||
this.data = MipmapTextureData(buffer, mipmaps)
|
||||
if (Thread.currentThread() == context.thread) {
|
||||
@ -147,7 +157,7 @@ abstract class DynamicTextureArray(
|
||||
for ((index, reference) in textures.withIndex()) {
|
||||
if (reference == null) continue
|
||||
val texture = reference.get()
|
||||
if (texture != null) continue // not gced yet, keep it for now
|
||||
if (texture != null && texture.state != DynamicTextureState.ERROR) continue // not gced yet, keep it for now
|
||||
textures[index] = null
|
||||
}
|
||||
lock.unlock()
|
||||
|
@ -17,6 +17,7 @@ enum class DynamicTextureState {
|
||||
WAITING,
|
||||
LOADING,
|
||||
LOADED,
|
||||
ERROR,
|
||||
|
||||
@Deprecated("unrechable", level = DeprecationLevel.ERROR)
|
||||
UNLOADED,
|
||||
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture.skin
|
||||
|
||||
class IllegalSkinError(message: String? = null) : Exception(message)
|
@ -30,13 +30,13 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY_INSTANCE
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.util.*
|
||||
|
||||
class SkinManager(private val textureManager: TextureManager) {
|
||||
class SkinManager(private val textures: TextureManager) {
|
||||
lateinit var default: DefaultSkinProvider
|
||||
private set
|
||||
private var skin: PlayerSkin? = null
|
||||
|
||||
fun initialize(account: Account, assets: AssetsManager) {
|
||||
default = DefaultSkinProvider(this.textureManager.dynamic, assets)
|
||||
default = DefaultSkinProvider(this.textures.dynamic, assets)
|
||||
default.initialize()
|
||||
skin = getSkin(account.uuid, account.properties, fetch = true, async = false)
|
||||
}
|
||||
@ -57,7 +57,7 @@ class SkinManager(private val textureManager: TextureManager) {
|
||||
|
||||
private fun getSkin(uuid: UUID, properties: PlayerProperties?, async: Boolean = true): PlayerSkin? {
|
||||
val texture = properties?.textures?.skin ?: return default[uuid]
|
||||
return PlayerSkin(textureManager.dynamic.push(texture.getHash(), async) { texture.read().readSkin() }, default[uuid]?.texture, texture.metadata.model)
|
||||
return PlayerSkin(textures.dynamic.push(texture.getHash(), async) { texture.read().readSkin() }, default[uuid]?.texture, texture.metadata.model)
|
||||
}
|
||||
|
||||
fun getSkin(player: PlayerEntity, properties: PlayerProperties? = null, fetch: Boolean = true, async: Boolean = true): PlayerSkin? {
|
||||
@ -76,16 +76,22 @@ class SkinManager(private val textureManager: TextureManager) {
|
||||
|
||||
private fun ByteArray.readSkin(): TextureBuffer {
|
||||
val data = ByteArrayInputStream(this).readTexture()
|
||||
if (data.size.y != 32) return data
|
||||
if (data.size.x != 64) throw IllegalSkinError("Width of skin must be 64 pixels: ${data.size}")
|
||||
return when (data.size.y) {
|
||||
32 -> {
|
||||
// <1.8 legacy skin
|
||||
val next = RGBA8Buffer(Vec2i(64))
|
||||
next.put(data, Vec2i.EMPTY_INSTANCE, Vec2i.EMPTY_INSTANCE, data.size)
|
||||
|
||||
val next = RGBA8Buffer(Vec2i(64))
|
||||
next.put(data, Vec2i.EMPTY_INSTANCE, Vec2i.EMPTY_INSTANCE, data.size)
|
||||
next.put(next, Vec2i(0, 16), Vec2i(16, 48), Vec2i(16, 16))// leg [0, 16][16,16] to left leg [16, 48]
|
||||
next.put(next, Vec2i(40, 16), Vec2i(32, 48), Vec2i(16, 16)) // arm [40, 16] to left arm [32, 48]
|
||||
|
||||
next.put(next, Vec2i(0, 16), Vec2i(16, 48), Vec2i(16, 16))// leg [0, 16][16,16] to left leg [16, 48]
|
||||
next.put(next, Vec2i(40, 16), Vec2i(32, 48), Vec2i(16, 16)) // arm [40, 16] to left arm [32, 48]
|
||||
// TODO: flip every texture part
|
||||
return data
|
||||
}
|
||||
|
||||
// TODO: flip every texture part
|
||||
|
||||
return next
|
||||
64 -> data // skin
|
||||
else -> throw IllegalSkinError("Can not detect skin format: ${data.size}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user