From 672b27e014d3b42d9fdb41332d290fcbdfa9a233 Mon Sep 17 00:00:00 2001 From: 0ffz Date: Thu, 14 Apr 2022 00:43:17 -0400 Subject: [PATCH] Rewrite to use paper's mapped userdev + reflection --- build.gradle.kts | 27 +++--- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- minecraft-data | 1 - .../protocolburrito/FieldHelpers.kt | 13 +++ protocolburrito-generator/build.gradle.kts | 36 ++++++-- .../generation/AnnotationProcessor.kt | 30 +++++-- .../protocolburrito/generation/Main.kt | 5 +- .../generation/PacketIdMapping.kt | 60 ------------- .../generation/ProtocolWrapperGenerator.kt | 84 +++++++++++++++++-- settings.gradle.kts | 19 ++++- 11 files changed, 182 insertions(+), 99 deletions(-) delete mode 160000 minecraft-data create mode 100644 protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt delete mode 100644 protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/PacketIdMapping.kt diff --git a/build.gradle.kts b/build.gradle.kts index 387a3b2..9551da1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,10 @@ plugins { kotlin("jvm") - kotlin("kapt") id("com.github.johnrengelman.shadow") version "7.0.0" id("com.mineinabyss.conventions.publication") id("de.undercouch.download") version "4.1.2" -// id("com.google.devtools.ksp") version "1.5.21-1.0.0-beta05" + id("com.mineinabyss.conventions.nms") + id("com.google.devtools.ksp") version "1.6.10-1.0.2" } repositories { @@ -31,32 +31,33 @@ allprojects { } dependencies { - compileOnly("org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT") + compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT") implementation(project(":protocolburrito-api")) compileOnly(project(":protocolburrito-generator")) - kapt(project(":protocolburrito-generator")) + ksp(project(":protocolburrito-generator")) } +sourceSets["main"].java.srcDir(file("$rootDir/protocolburrito-generator/build/generated/burrito/main")) + tasks { - val downloadMappings by register("Download mappings") { - src("https://launcher.mojang.com/v1/objects/f6cae1c5c1255f68ba4834b16a0da6a09621fe13/server.txt") - dest(file("mappings/server.txt")) - } +// val downloadMappings by register("Download mappings") { +// src("https://launcher.mojang.com/v1/objects/f6cae1c5c1255f68ba4834b16a0da6a09621fe13/server.txt") +// dest(file("mappings/server.txt")) +// } shadowJar { archiveClassifier.set("") } sourcesJar { from(sourceSets.main.get().allSource) - from("$buildDir/generated/source/kaptKotlin/main") } - publish { - dependsOn(downloadMappings) - } +// publish { +// dependsOn(downloadMappings) +// } build { - dependsOn(downloadMappings, project(":protocolburrito-plugin").tasks.build) + dependsOn(/*downloadMappings,*/ project(":protocolburrito-plugin").tasks.build) } } diff --git a/gradle.properties b/gradle.properties index 3b6cc47..aad0d58 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ version=0.2 group=com.mineinabyss kotlinVersion=1.6.10 -serverVersion=1.17.1-R0.1-SNAPSHOT -idofrontConventions=1.6.10-51 +serverVersion=1.18.2-R0.1-SNAPSHOT +idofrontVersion=0.9.82 # Workaround for Kapt not working on jdk 16 org.gradle.jvmargs=--illegal-access=permit diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 05679dc..00e33ed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/minecraft-data b/minecraft-data deleted file mode 160000 index 1117353..0000000 --- a/minecraft-data +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 111735398ff5972a2af7eae3bc2e00d879393174 diff --git a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt new file mode 100644 index 0000000..384a294 --- /dev/null +++ b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt @@ -0,0 +1,13 @@ +package com.mineinabyss.protocolburrito + +object FieldHelpers { + fun getField(forObject: Any, type: Class, index: Int): T { + var id = 0 + return forObject::class.java.fields.first { it.type.kotlin == type && index == id++ }.get(forObject) as T + } + + fun setField(forObject: Any, type: Class, index: Int, value: T) { + var id = 0 + forObject::class.java.fields.first { it.type == type && index == id++ }.set(forObject, value) + } +} diff --git a/protocolburrito-generator/build.gradle.kts b/protocolburrito-generator/build.gradle.kts index ebb6ca3..e9d37e6 100644 --- a/protocolburrito-generator/build.gradle.kts +++ b/protocolburrito-generator/build.gradle.kts @@ -1,25 +1,51 @@ +import io.papermc.paperweight.util.registering + +val serverVersion: String by project + plugins { kotlin("jvm") - kotlin("kapt") +// kotlin("kapt") +// id("com.mineinabyss.conventions.nms") + id("io.papermc.paperweight.userdev") } repositories { mavenCentral() google() + maven("https://papermc.io/repo/repository/maven-public/") } dependencies { - implementation("org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT") - implementation("com.comphenix.protocol:ProtocolLib:4.7.0") + paperDevBundle(serverVersion) + implementation(kotlin("reflect")) + implementation("io.papermc.paper:paper-server:userdev-1.18.2-R0.1-SNAPSHOT") +// implementation("com.comphenix.protocol:ProtocolLib:4.7.0") implementation("com.nfeld.jsonpathkt:jsonpathkt:2.0.0") implementation("com.squareup:kotlinpoet:1.10.1") implementation(project(":protocolburrito-api")) - implementation("com.google.devtools.ksp:symbol-processing-api:1.5.31-1.0.0") + implementation("com.google.devtools.ksp:symbol-processing-api:1.6.10-1.0.2") compileOnly("com.google.auto.service:auto-service:1.0") - kapt("com.google.auto.service:auto-service:1.0") +// kapt("com.google.auto.service:auto-service:1.0") + implementation("org.reflections:reflections:0.9.12") + implementation(kotlin("reflect")) +} +configurations { + remove(findByName("reobf")) } +tasks { + val generateBurrito by registering() { + main = "com.mineinabyss.protocolburrito.generation.MainKt" + classpath = files(configurations.runtimeClasspath, jar) + } + reobfJar { + onlyIf { false } + } + build { + dependsOn(generateBurrito) + } +} //sourceSets.main { // java.srcDirs("src/main/kotlin") //} diff --git a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/AnnotationProcessor.kt b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/AnnotationProcessor.kt index 6df501d..a173a01 100644 --- a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/AnnotationProcessor.kt +++ b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/AnnotationProcessor.kt @@ -1,6 +1,11 @@ package com.mineinabyss.protocolburrito.generation import com.google.auto.service.AutoService +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider +import com.google.devtools.ksp.symbol.KSAnnotated import javax.annotation.processing.* import javax.lang.model.SourceVersion import javax.lang.model.element.TypeElement @@ -15,17 +20,30 @@ annotation class RunGenerator @AutoService(Processor::class) @SupportedSourceVersion(SourceVersion.RELEASE_16) @SupportedOptions(AnnotationProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME) -class AnnotationProcessor : AbstractProcessor() { +class AnnotationProcessor( + val environment: SymbolProcessorEnvironment +) : SymbolProcessor { companion object { const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated" - var generatedDir: String = "build/generated/source/kaptKotlin/main/" + var generatedDir: String = "build/generated/burrito/main/" } - override fun getSupportedAnnotationTypes() = mutableSetOf(RunGenerator::class.java.name) +// override fun getSupportedAnnotationTypes() = mutableSetOf(RunGenerator::class.java.name) - override fun process(annotations: MutableSet, roundEnv: RoundEnvironment): Boolean { - generatedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME]!! +// override fun process(annotations: MutableSet, roundEnv: RoundEnvironment): Boolean { +// generatedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME]!! +// main() +// return false +// } + + override fun process(resolver: Resolver): List { main() - return false + return listOf() + } +} + +class ProtocolProcessorProvider: SymbolProcessorProvider { + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + return AnnotationProcessor(environment) } } diff --git a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/Main.kt b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/Main.kt index bffb9de..53a7b59 100644 --- a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/Main.kt +++ b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/Main.kt @@ -1,6 +1,7 @@ package com.mineinabyss.protocolburrito.generation fun main() { - generateEntityIdMapper() - generateProtocolWrappers() +// generateEntityIdMapper() +// generateProtocolWrappers() + generateProtocolExtensions() } diff --git a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/PacketIdMapping.kt b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/PacketIdMapping.kt deleted file mode 100644 index 419bc7b..0000000 --- a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/PacketIdMapping.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.mineinabyss.protocolburrito.generation - -import com.mineinabyss.protocolburrito.generation.AnnotationProcessor.Companion.generatedDir -import com.nfeld.jsonpathkt.JsonPath -import com.nfeld.jsonpathkt.extension.read -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeSpec -import java.io.File - -fun generateEntityIdMapper() { - generateNameToIDWrapper("PacketEntityType", "entities.json") - generateNameToIDWrapper("PacketBlocks", "blocks.json") - generateNameToIDWrapper("PacketItems", "items.json") - generateNameToIDWrapper("PacketBiomes", "biomes.json") -} - -fun generateNameToIDWrapper( - className: String, - fileName: String, - packageName: String = "com.mineinabyss.protocolburrito.enums", -) { - println("Generating enum for $fileName") - val entitiesFile = File(SERVER_PATH, fileName).readText() - val parsed: List> = JsonPath.parse(entitiesFile)?.read("$")!! - - val file = FileSpec.builder(packageName, className) - .addType( - TypeSpec - .enumBuilder(className) - //TODO is it worth having an id property or are we 100% guaranteed the ordinal is going to be id anyways? - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("id", Int::class) - .build() - ) - .addProperty( - PropertySpec.builder("id", Int::class) - .initializer("id") - .build() - ) - .apply { - parsed.forEach { type -> - val id = type["id"] as Int - val name = (type["name"] as String).toUpperCase() - - addEnumConstant( - name, TypeSpec.anonymousClassBuilder() - .addSuperclassConstructorParameter("$id") - .build() - ) - } - } - .build() - ) - .build() - - file.writeTo(File(AnnotationProcessor.generatedDir)) -} diff --git a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/ProtocolWrapperGenerator.kt b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/ProtocolWrapperGenerator.kt index fca87e2..9ab1fe6 100644 --- a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/ProtocolWrapperGenerator.kt +++ b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/ProtocolWrapperGenerator.kt @@ -1,23 +1,90 @@ package com.mineinabyss.protocolburrito.generation import com.comphenix.protocol.events.PacketContainer +import com.mineinabyss.protocolburrito.FieldHelpers import com.mineinabyss.protocolburrito.WrappedPacket import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import net.minecraft.network.protocol.Packet +import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.EntityType +import org.reflections.Reflections +import org.reflections.scanners.SubTypesScanner import java.io.File +import java.lang.reflect.Field +import java.lang.reflect.WildcardType import java.util.concurrent.atomic.AtomicInteger +import kotlin.reflect.KVisibility +import kotlin.reflect.javaType +import kotlin.reflect.typeOf + +//val SERVER_VERSION = "1.17" +//val PROJECT_ROOT = File("")//File(AnnotationProcessor.generatedDir)//.parentFile.parentFile.parentFile.parentFile.parentFile +//val SERVER_PATH = File(PROJECT_ROOT, "minecraft-data/data/pc/$SERVER_VERSION/") +//val MAPPINGS = File(PROJECT_ROOT, "mappings/server.txt") + + +@OptIn(DelicateKotlinPoetApi::class, ExperimentalStdlibApi::class) +fun generateProtocolExtensions() { + val classLoader = AnnotationProcessor::class.java.classLoader + val reflections = Reflections("net.minecraft.network.protocol.game", SubTypesScanner(false)) + reflections.getSubTypesOf(Packet::class.java).forEach { packetClass -> + val indices = mutableMapOf, AtomicInteger>() + val props = packetClass.declaredFields.mapNotNull { field -> + if(field.type.kotlin.visibility != KVisibility.PUBLIC) return@mapNotNull null + val index = indices.getOrPut(field.type) { AtomicInteger(0) } + PropertySpec.builder(field.name, field.type.let { + if(field.type.typeParameters.isNotEmpty()) { + if(it != EntityType::class.java) return@mapNotNull null + it.asClassName().parameterizedBy( + WildcardTypeName.producerOf(Entity::class.java) + ) + } + else it.asTypeName() + }) + .receiver(packetClass) + .getter( + FunSpec.getterBuilder() + .addStatement("return %T.getField(this, %T::class.java, ${index.toInt()})", FieldHelpers::class, field.type) + .build() + ) + .setter( + FunSpec.setterBuilder() + .addParameter(ParameterSpec.builder("value", field.type).build()) + .addCode("%T.setField(this, %T::class.java, ${index.toInt()}, value)", FieldHelpers::class, field.type) + .build() + ) + .mutable(true) + .build().also { + index.getAndAdd(1) + } + } + + val file = FileSpec.builder("com.mineinabyss.protocolburrito.packets", packetClass.simpleName + "Extensions") + .apply { + for(prop in props) { + addProperty(prop) + } + } + .build() + + file.writeTo(File(AnnotationProcessor.generatedDir)) + } +} +/* +data class Prop( + val typeInfo: TypeMap.TypeInfo<*>, + val name: String, +) -val SERVER_VERSION = "1.17" -val PROJECT_ROOT = File(AnnotationProcessor.generatedDir).parentFile.parentFile.parentFile.parentFile.parentFile -val SERVER_PATH = File(PROJECT_ROOT, "minecraft-data/data/pc/$SERVER_VERSION/") -val MAPPINGS = File(PROJECT_ROOT, "mappings/server.txt") fun generateProtocolWrappers() { var className: String? = null var props: MutableList? = null - val mappings = MAPPINGS.forEachLine { line -> + val mappings = MAPPINGS.forEachLine { line -> when { line.startsWith("net.minecraft.network.protocol.game") -> { - if(className != null && props?.isNotEmpty() == true) { + if (className != null && props?.isNotEmpty() == true) { runCatching { generateWrapper(className!!, props!!) }.onFailure { @@ -25,7 +92,8 @@ fun generateProtocolWrappers() { it.printStackTrace() } } - className = line.removePrefix("net.minecraft.network.protocol.game.").substringBefore(" ").substringBefore("$") + className = + line.removePrefix("net.minecraft.network.protocol.game.").substringBefore(" ").substringBefore("$") props = mutableListOf() } line.startsWith(" ") && props != null -> { @@ -37,6 +105,7 @@ fun generateProtocolWrappers() { } + data class Property( val typeInfo: TypeMap.TypeInfo<*>, val name: String, @@ -94,3 +163,4 @@ fun generateWrapper(packetName: String, params: List) { file.writeTo(File(AnnotationProcessor.generatedDir)) } +*/ diff --git a/settings.gradle.kts b/settings.gradle.kts index 3b0ceac..8f299fe 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,14 @@ rootProject.name = "protocolburrito" pluginManagement { - val idofrontConventions: String by settings + val idofrontVersion: String by settings repositories { gradlePluginPortal() mavenCentral() google() maven("https://repo.mineinabyss.com/releases") + maven("https://papermc.io/repo/repository/maven-public/") } plugins { @@ -20,7 +21,21 @@ pluginManagement { resolutionStrategy { eachPlugin { if (requested.id.id.startsWith("com.mineinabyss.conventions")) - useVersion(idofrontConventions) + useVersion(idofrontVersion) + } + } +} + +dependencyResolutionManagement { + val idofrontVersion: String by settings + + repositories { + maven("https://repo.mineinabyss.com/releases") + } + + versionCatalogs { + create("libs") { + from("com.mineinabyss:catalog:$idofrontVersion") } } }