verify block and item ids

This commit is contained in:
Moritz Zwerger 2023-10-06 13:12:32 +02:00
parent 91ace97457
commit 62585a9df5
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
8 changed files with 113 additions and 14 deletions

View File

@ -30,6 +30,8 @@ dependencies {
implementation("de.bixilon:kutil:1.23.2")
implementation("de.bixilon:mbf-kotlin:1.0.2")
implementation("it.unimi.dsi", "fastutil-core", "8.5.12")
testImplementation(kotlin("test"))
}

View File

@ -13,7 +13,6 @@ import de.bixilon.mbf.MBFBinaryWriter
import de.bixilon.mbf.MBFCompressionTypes
import de.bixilon.mbf.MBFData
import de.bixilon.mbf.MBFDataInfo
import de.bixilon.minosoft.meta.transpiler.processors.GenericProcessor
import de.bixilon.minosoft.meta.transpiler.processors.Processors
import java.io.*
import java.util.*
@ -45,7 +44,8 @@ object MinosoftMetaTranspiler {
if (error.isNotEmpty()) {
for (error in error) {
System.err.println("Error in version ${error.version} in type ${error.type}: ${error.cause}")
System.err.println("Error in version ${error.version} in type ${error.type}:")
error.cause!!.printStackTrace()
}
exitProcess(1)
}
@ -93,12 +93,12 @@ object MinosoftMetaTranspiler {
}
private fun readFile(stream: InputStream, version: String, type: String, output: File) {
val processor = Processors.types[type] ?: GenericProcessor
val processor = Processors.types[type]?.build()
try {
println("Validating $type ($version)")
total.incrementAndGet()
val json: JsonObject = Jackson.MAPPER.readValue(stream)
processor.validate(json)
processor?.validate(json)
val hash = storeMbf(json, output)
val entry = MetaVersionEntry(version, hash)
mbf.synchronizedGetOrPut(type) { Collections.synchronizedList(mutableListOf()) } += entry

View File

@ -0,0 +1,51 @@
package de.bixilon.minosoft.meta.transpiler.processors
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.primitive.IntUtil.toInt
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
class BlockProcessor : Processor {
private val ids = IntOpenHashSet()
private fun validateId(identifier: String, data: JsonObject): Int {
val id = data["id"]!!.toInt()
if (id < 1) throw IllegalArgumentException("Id < 1: $id for item $identifier")
if (id > 0xFF) throw IllegalArgumentException("Id > 0xFF: $id for item $identifier")
return id
}
private fun validateMeta(identifier: String, data: JsonObject): Int {
val meta = data["meta"]?.toInt() ?: return 0
if (meta < 0) throw IllegalArgumentException("Meta < 0: $meta for item $identifier")
if (meta > 0x0F) throw IllegalArgumentException("Meta > 0x0F: $meta for item $identifier")
return meta
}
override fun validateEntry(identifier: String, data: JsonObject) {
val states = data["states"]
if (states != null) {
return validateStates(identifier, states.unsafeCast())
}
validateIdAndMeta(identifier, data)
}
private fun validateStates(identifier: String, states: List<JsonObject>) {
for (entry in states) {
validateIdAndMeta(identifier, entry)
}
}
private fun validateIdAndMeta(identifier: String, data: JsonObject) {
val id = validateId(identifier, data)
val meta = validateMeta(identifier, data)
val combined = id shl 4 or meta
if (!ids.add(combined)) {
throw IllegalStateException("Id duplicated $id (meta=$meta)")
}
}
companion object : ProcessorBuilder {
override fun build() = BlockProcessor()
}
}

View File

@ -1,7 +0,0 @@
package de.bixilon.minosoft.meta.transpiler.processors
import de.bixilon.kutil.json.JsonObject
object GenericProcessor : Processor {
override fun validate(data: JsonObject) = Unit
}

View File

@ -0,0 +1,38 @@
package de.bixilon.minosoft.meta.transpiler.processors
import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.primitive.IntUtil.toInt
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
class ItemProcessor : Processor {
private val ids = IntOpenHashSet()
private fun validateId(identifier: String, data: JsonObject): Int {
val id = data["id"]!!.toInt()
if (id < 1) throw IllegalArgumentException("Id < 1: $id for item $identifier")
if (id > 0xFFFF) throw IllegalArgumentException("Id > 0xFFFF: $id for item $identifier")
return id
}
private fun validateMeta(identifier: String, data: JsonObject): Int {
val meta = data["meta"]?.toInt() ?: return 0
if (meta < 0) throw IllegalArgumentException("Meta < 0: $meta for item $identifier")
if (meta > 0xFFFF) throw IllegalArgumentException("Meta > 0xFFFF: $meta for item $identifier")
return meta
}
override fun validateEntry(identifier: String, data: JsonObject) {
val id = validateId(identifier, data)
val meta = validateMeta(identifier, data)
val combined = id shl 16 or meta
if (!this.ids.add(combined)) {
throw IllegalStateException("Id duplicated: $id (meta=$meta)")
}
}
companion object : ProcessorBuilder {
override fun build() = ItemProcessor()
}
}

View File

@ -1,7 +1,15 @@
package de.bixilon.minosoft.meta.transpiler.processors
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
interface Processor {
fun validate(data: JsonObject)
fun validate(data: JsonObject) {
for ((key, value) in data) {
validateEntry(key.removePrefix("minecraft:"), value.unsafeCast())
}
}
fun validateEntry(identifier: String, data: JsonObject)
}

View File

@ -0,0 +1,6 @@
package de.bixilon.minosoft.meta.transpiler.processors
fun interface ProcessorBuilder {
fun build(): Processor
}

View File

@ -1,7 +1,8 @@
package de.bixilon.minosoft.meta.transpiler.processors
object Processors {
val types: MutableMap<String, Processor> = mutableMapOf(
val types: MutableMap<String, ProcessorBuilder> = mutableMapOf(
"items" to ItemProcessor,
"blocks" to BlockProcessor,
)
}