assets: fix a ton of stuff

This commit is contained in:
Bixilon 2021-12-12 15:13:58 +01:00
parent e929d80cae
commit f6e964a643
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 76 additions and 7 deletions

View File

@ -8,14 +8,18 @@ import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties
import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperty
import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile
import de.bixilon.minosoft.data.registries.versions.Version
import de.bixilon.minosoft.util.CountUpAndDownLatch
object AssetsLoader {
fun create(profile: ResourcesProfile, version: Version, property: AssetsVersionProperty = AssetsVersionProperties[version] ?: throw IllegalAccessException("$version has no assets!")): AssetsManager {
fun create(profile: ResourcesProfile, version: Version, latch: CountUpAndDownLatch, property: AssetsVersionProperty = AssetsVersionProperties[version] ?: throw IllegalAccessException("$version has no assets!")): AssetsManager {
val assetsManager = PriorityAssetsManager()
for (resourcePack in profile.assets.resourcePacks) {
assetsManager += resourcePack.type.creator(resourcePack)
resourcePack.type.creator(resourcePack).let {
it.load(latch)
assetsManager += it
}
}
if (!profile.assets.disableIndexAssets) {

View File

@ -20,6 +20,7 @@ import java.io.FileNotFoundException
import java.io.InputStream
interface AssetsManager : Iterable<Map.Entry<ResourceLocation, ByteArray>> {
/**
* All namespaces this assets-manager can provide
*/
@ -37,6 +38,7 @@ interface AssetsManager : Iterable<Map.Entry<ResourceLocation, ByteArray>> {
val properties: AssetsManagerProperties?
get() = null
val loaded: Boolean
/**
* Returns the input stream of an asset or throws FileNotFoundException

View File

@ -32,6 +32,8 @@ class DirectoryAssetsManager(
) : AssetsManager {
override val namespaces: MutableSet<String> = mutableSetOf()
private var assets: MutableSet<ResourceLocation> = mutableSetOf()
override var loaded: Boolean = false
private set
private val ResourceLocation.filePath: String
get() = "$basePath/$namespace/$path"
@ -51,11 +53,14 @@ class DirectoryAssetsManager(
}
override fun load(latch: CountUpAndDownLatch) {
check(!loaded) { "Already loaded!" }
scanDirectory(File(basePath))
loaded = true
}
override fun unload() {
assets.clear()
loaded = false
}
override fun iterator(): Iterator<Map.Entry<ResourceLocation, ByteArray>> {

View File

@ -21,6 +21,8 @@ import java.io.FileNotFoundException
import java.io.InputStream
abstract class FileAssetsManager : AssetsManager {
override var loaded: Boolean = false
protected set
override var image: ByteArray? = null
protected set
override var properties: AssetsManagerProperties? = null
@ -40,6 +42,7 @@ abstract class FileAssetsManager : AssetsManager {
override fun unload() {
assets.clear()
loaded = false
}
override fun iterator(): Iterator<Map.Entry<ResourceLocation, ByteArray>> {

View File

@ -29,22 +29,28 @@ class ZipAssetsManager(
) : FileAssetsManager() {
override fun load(latch: CountUpAndDownLatch) {
check(!loaded) { "Already loaded!" }
val namespaces: MutableSet<String> = mutableSetOf()
while (true) {
val entry = inputStream.nextEntry ?: break
if (entry.isDirectory) {
continue
}
when (val name = entry.name) {
"pack.png" -> image = inputStream.readAllBytes()
"pack.mcmeta" -> properties = inputStream.readJson()
"pack.mcmeta" -> properties = inputStream.readJson(false)
else -> {
val resourceLocation = name.toAssetName() ?: continue
namespaces += resourceLocation.namespace
assets[resourceLocation] = inputStream.readAllBytes()
}
}
inputStream.closeEntry()
}
inputStream.close()
this.namespaces = namespaces
loaded = true
}
constructor(file: File) : this(ZipInputStream(FileInputStream(file)))

View File

@ -40,10 +40,14 @@ class JarAssetsManager(
val profile: ResourcesProfile,
val version: Version,
) : MinecraftAssetsManager {
override var loaded: Boolean = false
private set
override val namespaces = setOf(ProtocolDefinition.DEFAULT_NAMESPACE)
private var jarAssets: MutableMap<String, ByteArray> = mutableMapOf()
override fun load(latch: CountUpAndDownLatch) {
check(!loaded) { "Already loaded!" }
val jarAssetFile = File(FileAssetsUtil.getPath(jarAssetsHash))
if (FileAssetsUtil.verifyAsset(jarAssetsHash, jarAssetFile, profile.verify)) {
val jarAssets = FileUtil.readFile(jarAssetFile).readArchive()
@ -100,6 +104,7 @@ class JarAssetsManager(
this.jarAssets = buildingJarAsset
}
loaded = true
}
override fun get(path: ResourceLocation): InputStream {
@ -116,6 +121,7 @@ class JarAssetsManager(
override fun unload() {
jarAssets = mutableMapOf()
loaded = false
}
override fun iterator(): Iterator<Map.Entry<ResourceLocation, ByteArray>> {

View File

@ -50,6 +50,8 @@ class IndexAssetsManager(
private val verify: Boolean = profile.verify
private val assets: MutableMap<ResourceLocation, AssetsProperty> = synchronizedMapOf()
override val namespaces: Set<String> = setOf(ProtocolDefinition.DEFAULT_NAMESPACE)
override var loaded: Boolean = false
private set
private fun downloadAssetsIndex(): Map<String, Any> {
return Jackson.MAPPER.readValue(FileAssetsUtil.downloadAndGetAsset(Util.formatString(profile.source.mojangPackages,
@ -77,6 +79,8 @@ class IndexAssetsManager(
}
override fun load(latch: CountUpAndDownLatch) {
check(!loaded) { "Already loaded!" }
var assets = FileUtil.saveReadFile(FileAssetsUtil.getPath(indexHash))?.readJsonObject() ?: downloadAssetsIndex()
assets["objects"].let { assets = it.asCompound() }
@ -120,13 +124,17 @@ class IndexAssetsManager(
}
}
assetsLatch.await()
loaded = true
}
override fun iterator(): Iterator<Map.Entry<ResourceLocation, ByteArray>> {
TODO("Not yet implemented")
}
override fun unload() {}
override fun unload() {
assets.clear()
loaded = false
}
override fun get(path: ResourceLocation): InputStream {
return FileUtil.readFile(FileAssetsUtil.getPath(assets[path]?.hash ?: throw FileNotFoundException("Could not find asset $path")))

View File

@ -27,6 +27,17 @@ class PriorityAssetsManager(
) : MultiAssetsManager {
private val managers: MutableMap<String, MutableSet<AssetsManager>> = mutableMapOf()
override val namespaces: MutableSet<String> = mutableSetOf()
override val loaded: Boolean
get() {
for (managers in managers.values) {
for (manager in managers) {
if (!manager.loaded) {
return false
}
}
}
return true
}
init {
for (manager in managers) {
@ -67,6 +78,9 @@ class PriorityAssetsManager(
override fun load(latch: CountUpAndDownLatch) {
for ((_, managers) in managers) {
for (manager in managers) {
if (manager.loaded) {
continue
}
manager.load(latch)
}
}

View File

@ -22,7 +22,11 @@ import de.matthiasmann.twl.utils.PNGDecoder
import glm_.vec2.Vec2
import glm_.vec2.Vec2i
import org.lwjgl.BufferUtils
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import java.nio.ByteBuffer
import javax.imageio.ImageIO
class PNGTexture(override val resourceLocation: ResourceLocation) : AbstractTexture {
@ -49,7 +53,22 @@ class PNGTexture(override val resourceLocation: ResourceLocation) : AbstractText
val decoder = PNGDecoder(assetsManager[resourceLocation])
val data = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGBA.numComponents)
decoder.decode(data, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA)
try {
decoder.decode(data, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA)
} catch (exception: Throwable) {
// ToDo: This somehow crashes with some resource packs
// exception.printStackTrace()
val image: BufferedImage = ImageIO.read(assetsManager[resourceLocation])
val rgb = image.getRGB(0, 0, image.width, image.height, null, 0, image.width)
val byteOutput = ByteArrayOutputStream()
val dataOutput = DataOutputStream(byteOutput)
for (color in rgb) {
dataOutput.writeInt(color)
}
data.put(byteOutput.toByteArray())
}
size = Vec2i(decoder.width, decoder.height)
transparency = TextureTransparencies.OPAQUE

View File

@ -220,8 +220,8 @@ class PlayConnection(
version.load(profiles.resources)
registries.parentRegistries = version.registries
assetsManager = AssetsLoader.create(profiles.resources, version)
Log.log(LogMessageType.ASSETS, LogLevels.INFO) { "Downloading and verifying assets. This might take a while..." }
assetsManager = AssetsLoader.create(profiles.resources, version, latch)
assetsManager.load(latch)
Log.log(LogMessageType.ASSETS, LogLevels.INFO) { "Assets verified!" }

View File

@ -1,5 +1,6 @@
package de.bixilon.minosoft.util.json
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.PropertyNamingStrategies
@ -21,6 +22,7 @@ object Jackson {
.registerModule(RGBColorSerializer)
.registerModule(ChatComponentColorSerializer)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE)
.setDefaultMergeable(true)