Add generator for tags
This commit is contained in:
parent
468273eb6d
commit
310fe37c21
11 changed files with 153 additions and 49 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,8 +2,8 @@
|
|||
build/
|
||||
!src/**/build
|
||||
|
||||
/data/
|
||||
/serverData/
|
||||
|
||||
/minecraft-data/
|
||||
/buildSrcTemp/
|
||||
|
||||
generatedKotlin/
|
||||
|
|
17
blokk-api/src/main/kotlin/space/blokk/tags/Tag.kt
Normal file
17
blokk-api/src/main/kotlin/space/blokk/tags/Tag.kt
Normal 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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package space.blokk.tags
|
||||
|
||||
object TagRegistry {
|
||||
val tags: Map<String, Tag> = getTags()
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
5
buildSrc/src/main/kotlin/space/blokk/mdsp/Constants.kt
Normal file
5
buildSrc/src/main/kotlin/space/blokk/mdsp/Constants.kt
Normal 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
|
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
|
@ -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)
|
||||
}
|
||||
}
|
Reference in a new issue