Archived
1
0
Fork 0

Add generator for tags

This commit is contained in:
Moritz Ruth 2020-11-29 21:14:34 +01:00
parent 468273eb6d
commit 310fe37c21
11 changed files with 153 additions and 49 deletions

4
.gitignore vendored
View file

@ -2,8 +2,8 @@
build/
!src/**/build
/data/
/serverData/
/minecraft-data/
/buildSrcTemp/
generatedKotlin/

View file

@ -0,0 +1,17 @@
package space.blokk.tags
class Tag(val name: String, val type: Type, val rawValues: List<String>) {
val values: List<String> by lazy {
rawValues.flatMap {
if (it.startsWith("#")) TagRegistry.tags.getValue(it.removePrefix("#")).values
else listOf(it)
}
}
enum class Type {
BLOCKS,
ENTITY_TYPES,
FLUIDS,
ITEMS
}
}

View file

@ -0,0 +1,5 @@
package space.blokk.tags
object TagRegistry {
val tags: Map<String, Tag> = getTags()
}

View file

@ -45,7 +45,7 @@ class BlokkServer internal constructor() : Server {
override val serverDirectory: File = run {
var dir = File(BlokkServer::class.java.protectionDomain.codeSource.location.toURI())
if (VERSION == "development") dir = dir.resolve("../../../../../data").normalize().also { it.mkdirs() }
if (VERSION == "development") dir = dir.resolve("../../../../../serverData").normalize().also { it.mkdirs() }
dir
}

View file

@ -7,19 +7,15 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import java.io.File
import java.util.*
typealias JsonAny = com.jsoniter.any.Any
class FilesGenerator(private val dataDir: File, private val outputDir: File, private val sourcesDir: File) {
class BlocksAndMaterialGenerator(
private val workingDir: File,
private val outputDir: File,
private val sourcesDir: File
) {
companion object {
const val IMPORT_FOR_REMOVAL_PACKAGE_NAME = "IMPORT_FOR_REMOVAL"
const val PROPERTY_TYPE_FOR_REMOVAL_NAME = "PROPERTY_TYPE_FOR_REMOVAL"
const val API_PACKAGE = "space.blokk"
const val BLOCK_PACKAGE = "space.blokk.world.block"
val MATERIAL_TYPE = ClassName(BLOCK_PACKAGE, "Material")
val BLOCK_TYPE = ClassName(BLOCK_PACKAGE, "Block")
val BLOCK_REF_TYPE = ClassName(BLOCK_PACKAGE, "BlockRef")
val BLOCK_CODEC_TYPE = BLOCK_TYPE.nestedClass("Codec")
val K_CLASS_TYPE = ClassName("kotlin.reflect", "KClass")
val MAP_TYPE = ClassName("kotlin.collections", "Map")
}
@ -28,11 +24,11 @@ class FilesGenerator(private val dataDir: File, private val outputDir: File, pri
outputDir.deleteRecursively()
outputDir.mkdirs()
val collisionShapesJson = dataDir.resolve("blockCollisionShapes.json").readText()
val collisionShapesJson = workingDir.resolve("blockCollisionShapes.json").readText()
val collisionShapesData = JsonIterator.deserialize(collisionShapesJson)
generateCollisionShapeEnum(collisionShapesData.get("shapes").asMap())
val dataJson = dataDir.resolve("blocks.json").readText()
val dataJson = workingDir.resolve("blocks.json").readText()
val blocks = JsonIterator.deserialize(dataJson).asList()
generateBlockStubs(blocks)

View file

@ -0,0 +1,5 @@
package space.blokk.mdsp
const val PRISMARINE_BASE_URL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/"
typealias JsonAny = com.jsoniter.any.Any

View file

@ -5,22 +5,19 @@ import okhttp3.Request
import java.io.File
import kotlin.time.measureTime
class DataDownloader(val dir: File) {
class DataDownloader(private val dir: File) {
private val client = OkHttpClient()
fun start() {
FILES.forEach { name ->
val file = dir.resolve("$name.json")
FILES.forEach { (name, url) ->
val file = dir.resolve(name)
file.parentFile.mkdirs()
val fileName = file.name
if (file.exists()) {
println("$fileName already exists, skipping download")
} else {
if (file.exists()) println("name already exists, skipping download")
else {
val request = Request.Builder()
.get()
.url("$BASE_URL/$MINECRAFT_VERSION_OF_PRISMARINE_DATA/$name.json")
.url(url)
.build()
val time = measureTime {
@ -28,11 +25,11 @@ class DataDownloader(val dir: File) {
if (it.isSuccessful) {
file.createNewFile()
it.body!!.byteStream().copyTo(file.outputStream())
} else throw DownloadException(fileName)
} else throw DownloadException(name)
}
}
println("Downloaded $fileName in ${time.inSeconds}s")
println("Downloaded $name in ${time.inSeconds}s")
}
}
}
@ -40,11 +37,10 @@ class DataDownloader(val dir: File) {
class DownloadException(fileName: String) : Exception("Downloading $fileName failed")
companion object {
const val BASE_URL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/"
val FILES = arrayOf(
"blocks",
"blockCollisionShapes"
val FILES = mapOf(
"minecraft_server.jar" to "https://launcher.mojang.com/v1/objects/4d1826eebac84847c71a77f9349cc22afd0cf0a1/server.jar",
"blocks.json" to PRISMARINE_BASE_URL + "1.15.2/blocks.json",
"blockCollisionShapes.json" to PRISMARINE_BASE_URL + "1.15.2/blockCollisionShapes.json"
)
}
}

View file

@ -0,0 +1,27 @@
package space.blokk.mdsp
import java.io.File
class DataGeneratorRunner(private val workingDir: File, private val outputDir: File) {
fun generate() {
val minecraftServerFile = workingDir.resolve("minecraft_server.jar")
val javaBinDir = File(System.getProperty("java.home")).resolve("bin")
val javaExecutable = javaBinDir.resolve("java")
.run { if (exists()) this else javaBinDir.resolve("java.exe") }
val process = ProcessBuilder()
.command(
javaExecutable.absolutePath,
"-cp",
minecraftServerFile.absolutePath,
"net.minecraft.data.Main",
"--server"
)
.directory(workingDir)
.start()
process.waitFor()
process.inputStream.transferTo(System.out)
}
}

View file

@ -5,30 +5,41 @@ import org.gradle.api.Project
class MinecraftDataSourcesPlugin : Plugin<Project> {
override fun apply(project: Project) {
val workingDir = project.file("buildSrcTemp")
val outputDir = project
.project(":blokk-api")
.projectDir
.resolve("src/main/generatedKotlin")
val sourcesDir = project
.project(":blokk-api")
.projectDir
.resolve("src/main/kotlin")
val downloadTask = project.task("downloadMinecraftData") {
it.group = TASK_GROUP
it.doLast {
DataDownloader(project.file("minecraft-data")).start()
DataDownloader(workingDir).start()
}
}
project.task("generateAPIFiles") {
project.task("runDataGenerators") {
it.group = TASK_GROUP
it.dependsOn(downloadTask)
it.doLast {
FilesGenerator(
project.file("minecraft-data"),
project
.project(":blokk-api")
.projectDir
.resolve("src/main/generatedKotlin"),
project
.project(":blokk-api")
.projectDir
.resolve("src/main/kotlin")
).generate()
DataGeneratorRunner(workingDir, outputDir).generate()
}
}
project.task("generate") {
it.group = TASK_GROUP
it.dependsOn(downloadTask)
it.doLast {
BlocksAndMaterialGenerator(workingDir, outputDir, sourcesDir).generate()
TagsFileGenerator(workingDir, outputDir).generate()
}
}
}

View file

@ -1,6 +0,0 @@
package space.blokk.mdsp
/**
* Some Minecraft versions do not have own data files in the Prismarine repository.
*/
const val MINECRAFT_VERSION_OF_PRISMARINE_DATA = "1.15.2"

View file

@ -0,0 +1,53 @@
package space.blokk.mdsp
import com.jsoniter.JsonIterator
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import java.io.File
class TagsFileGenerator(val workingDir: File, val outputDir: File) {
companion object {
const val TAGS_PACKAGE = "space.blokk.tags"
val TAG_TYPE = ClassName(TAGS_PACKAGE, "Tag")
val TAG_TYPE_TYPE = TAG_TYPE.nestedClass("Type")
val TAG_TYPE_TYPES_BY_DIR_NAME = mapOf(
"blocks" to TAG_TYPE_TYPE.nestedClass("BLOCKS"),
"entity_types" to TAG_TYPE_TYPE.nestedClass("ENTITY_TYPES"),
"fluids" to TAG_TYPE_TYPE.nestedClass("FLUIDS"),
"items" to TAG_TYPE_TYPE.nestedClass("ITEMS")
)
}
val tagsDir = workingDir.resolve("generated/data/minecraft/tags")
fun generate() {
val entries: List<Pair<String, Array<Any>>> = TAG_TYPE_TYPES_BY_DIR_NAME.flatMap { (dirName, tagTypeType) ->
tagsDir.resolve(dirName).listFiles()!!.map { file ->
val name = file.nameWithoutExtension
val json = JsonIterator.deserialize(file.readText())
val values = json.get("values").asList().map { it.toString() }
Pair(
"%S to %T(%S, %T, listOf(\n${values.joinToString(",\n") { "%S".prependIndent(" ") }}\n))",
arrayOf(name, TAG_TYPE, name, tagTypeType, *values.toTypedArray())
)
}
}
val function = FunSpec.builder("getTags")
.addStatement(
"return mapOf(\n${entries.joinToString(",\n") { it.first.prependIndent(" ") }}\n)",
*entries.flatMap { it.second.toList() }.toTypedArray()
)
.addModifiers(KModifier.INTERNAL)
.build()
FileSpec.builder(TAGS_PACKAGE, "Tags")
.addFunction(function)
.build()
.writeTo(outputDir)
}
}