diff --git a/build.gradle.kts b/build.gradle.kts index a616497..8a9891a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ allprojects { repositories { maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") maven("https://repo.dmulloy2.net/nexus/repository/public/")//ProtocolLib - maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + maven("https://repo.papermc.io/repository/maven-public/") } val libs = rootProject.idofrontLibs diff --git a/gradle.properties b/gradle.properties index ecc762c..1e07d92 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=0.9 +version=0.10 group=com.mineinabyss idofrontVersion=0.22.3 publishComponentName=java diff --git a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt index 30d3d96..e60ee06 100644 --- a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt +++ b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/FieldHelpers.kt @@ -1,5 +1,7 @@ package com.mineinabyss.protocolburrito +import com.comphenix.protocol.events.PacketContainer + object FieldHelpers { inline fun getField(forObject: Any, index: Int): T = getField(T::class.java, forObject, index) diff --git a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedCompanion.kt b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedCompanion.kt index 35d69f1..bf5e398 100644 --- a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedCompanion.kt +++ b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedCompanion.kt @@ -4,7 +4,7 @@ import com.comphenix.protocol.PacketType import com.comphenix.protocol.injector.packet.PacketRegistry interface WrappedCompanion { - val type: PacketType + val packetType: PacketType fun wrap(any: Any): Any } diff --git a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedPacket.kt b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedPacket.kt index 9dc9823..881b633 100644 --- a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedPacket.kt +++ b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/WrappedPacket.kt @@ -1,3 +1,7 @@ package com.mineinabyss.protocolburrito -interface WrappedPacket +import com.comphenix.protocol.events.PacketContainer + +interface WrappedPacket { + val container: PacketContainer +} diff --git a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/dsl/ProtocolManagerBurrito.kt b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/dsl/ProtocolManagerBurrito.kt index 1b08228..3e9df17 100644 --- a/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/dsl/ProtocolManagerBurrito.kt +++ b/protocolburrito-api/src/main/kotlin/com/mineinabyss/protocolburrito/dsl/ProtocolManagerBurrito.kt @@ -28,7 +28,7 @@ class ProtocolManagerBurrito( crossinline onSend: PacketEvent.(wrapped: T) -> Unit ) { val companion = T::class.companionObjectInstance as WrappedCompanion - onSend(companion.type, priority = priority) { onSend(companion.wrap(packet.handle) as T) } + onSend(companion.packetType, priority = priority) { onSend(companion.wrap(packet.handle) as T) } } inline fun onSend( @@ -48,7 +48,7 @@ class ProtocolManagerBurrito( crossinline onReceive: PacketEvent.(wrapped: T) -> Unit ) { val companion = T::class.companionObjectInstance as WrappedCompanion - onReceive(companion.type, priority = priority) { onReceive(companion.wrap(packet.handle) as T) } + onReceive(companion.packetType, priority = priority) { onReceive(companion.wrap(packet.handle) as T) } } inline fun onReceive( 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 112226f..e409a87 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,6 +1,7 @@ package com.mineinabyss.protocolburrito.generation import com.comphenix.protocol.PacketType +import com.comphenix.protocol.events.PacketContainer import com.comphenix.protocol.injector.packet.PacketRegistry import com.mineinabyss.protocolburrito.FieldHelpers import com.mineinabyss.protocolburrito.WrappedCompanion @@ -11,36 +12,59 @@ import org.reflections.Reflections import org.reflections.scanners.SubTypesScanner import java.io.File import java.util.concurrent.atomic.AtomicInteger -import kotlin.reflect.KType +import kotlin.reflect.KClass import kotlin.reflect.KVisibility import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.jvm.jvmErasure val OUTPUT_DIR = File("build/generated/burrito/main/") +@OptIn(ExperimentalStdlibApi::class) fun generateProtocolExtensions() { val reflections = Reflections("net.minecraft.network.protocol.game", SubTypesScanner(false)) reflections.getSubTypesOf(Packet::class.java) .map { it.kotlin } .filter { !it.isAbstract } .forEach { packetClass -> - val indices = mutableMapOf() + val indices = mutableMapOf, AtomicInteger>() val props = packetClass.declaredMemberProperties.mapNotNull { field -> + val type = field.returnType if (field.visibility == KVisibility.PUBLIC) return@mapNotNull null - if (field.returnType.jvmErasure.visibility != KVisibility.PUBLIC) return@mapNotNull null - if (field.returnType.arguments.any { it.type?.jvmErasure?.visibility != KVisibility.PUBLIC }) return@mapNotNull null - val index = indices.getOrPut(type) { AtomicInteger(0) } - PropertySpec.builder(field.name, type.asTypeName().copy(annotations = listOf())) //.let { + val typeInfo = TypeMap.getStructureModifier(type) ?: run { + println("Creating ${packetClass.simpleName}") + println("Failed to find structure modifier on (name=${field.name}, type=$type, erased=${type.jvmErasure})") + if (field.returnType.jvmErasure.visibility != KVisibility.PUBLIC) return@mapNotNull null + if (field.returnType.arguments.any { it.type?.jvmErasure?.visibility != KVisibility.PUBLIC }) return@mapNotNull null + null + } + val useType = typeInfo?.type ?: type.asTypeName() + val index = indices.getOrPut(type.jvmErasure) { AtomicInteger(0) } + PropertySpec.builder(field.name, useType.copy(annotations = listOf())) .getter( - FunSpec.getterBuilder() - .addStatement("return %T.getField(handle, ${index.toInt()})", FieldHelpers::class) + FunSpec.getterBuilder().run { + if (typeInfo != null) + addStatement( + "return container.%N().read(${index.toInt()})", + typeInfo.structureModifierMember + ) + else + addStatement("return %T.getField(handle, ${index.toInt()})", FieldHelpers::class) + } .build() ) .setter( FunSpec.setterBuilder() .addParameter(ParameterSpec.builder("value", type.asTypeName()).build()) - .addCode("%T.setField(handle, ${index.toInt()}, value)", FieldHelpers::class) + .run { + if (typeInfo != null) + addCode( + "container.%N().write(${index.toInt()}, value)", + typeInfo.structureModifierMember + ) + else + addCode("%T.setField(handle, ${index.toInt()}, value)", FieldHelpers::class) + } .build() ) .mutable(true) @@ -62,13 +86,18 @@ fun generateProtocolExtensions() { PropertySpec.builder("handle", Any::class/*packetClass*/).build() ) // .addProperty("handle", packetClass) + .addProperty( + PropertySpec.builder("container", PacketContainer::class, KModifier.OVERRIDE) + .initializer("PacketContainer(packetType, handle)") + .build() + ) .addProperties(props) .addType( TypeSpec .companionObjectBuilder() .addSuperinterface(WrappedCompanion::class) .addProperty( - PropertySpec.builder("type", PacketType::class) + PropertySpec.builder("packetType", PacketType::class) .addModifiers(KModifier.OVERRIDE) .getter( FunSpec.getterBuilder() diff --git a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/TypeMap.kt b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/TypeMap.kt index 1b569c2..a37e404 100644 --- a/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/TypeMap.kt +++ b/protocolburrito-generator/src/main/kotlin/com/mineinabyss/protocolburrito/generation/TypeMap.kt @@ -1,47 +1,140 @@ package com.mineinabyss.protocolburrito.generation import com.comphenix.protocol.events.PacketContainer -import com.comphenix.protocol.reflect.StructureModifier -import org.bukkit.entity.Entity -import kotlin.reflect.KClass -import kotlin.reflect.KFunction1 +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.MemberName.Companion.member +import it.unimi.dsi.fastutil.objects.Object2IntMap +import net.minecraft.stats.Stat +import java.util.* +import kotlin.reflect.* +import kotlin.reflect.full.withNullability object TypeMap { - class TypeInfo( - val kClass: KClass, - val structureModified: KFunction1> + class TypeInfo( + val type: TypeName, + val structureModifierMember: MemberName +// val structureModifier: KFunction1> ) - inline fun get(function: KFunction1>): TypeInfo { - return TypeInfo(T::class, function) +// inline fun get(function: KFunction1>): TypeInfo { +// return TypeInfo(T::class, function) +// } +// +// val types = mapOf( +// // Arrays +// //TODO doesnt work because Array gets type erased +//// "java.lang.String[]" to get>(PacketContainer::getStringArrays), +// "byte[]" to get(PacketContainer::getByteArrays), +// "int[]" to get(PacketContainer::getIntegerArrays), +// "short[]" to get(PacketContainer::getShortArrays), +// "net.minecraft.world.entity.EntityType" to get(PacketContainer::getEntityTypeModifier), +// "net.minecraft.core.BlockPos" to get(PacketContainer::getBlockPositionModifier), +// //TODO UNSURE +// "net.minecraft.network.chat.Component" to get(PacketContainer::getChatComponents), +// //TODO figure something out with this modifier, requires world parameter pass +//// "net.minecraft.world.entity.Entity" to get(PacketContainer::getEntityModifier), +// ) + + @OptIn(ExperimentalStdlibApi::class) + fun getStructureModifier(type: KType): TypeInfo? { +// val type = type.withNullability(false) +// val singleArgument = type.arguments.singleOrNull()?.type?.withNullability(false) +// if(singleArgument != null) { +// val outerType = outerModifier[type.jvmErasure] +// println("Working on $type with args ${type.arguments}, and erased ${type.jvmErasure}") +// if (outerType != null) { +// println(FunSpec.builder("test").addStatement("val test = %N", outerType).build()) +// } +// +// leafModifier[singleArgument] +// +// println("Got type $outerType") +// } + val modifier = mappedLeafModifiers[type.javaType] ?: return null + val structureModifierName = modifier.name + val fieldType = modifier.returnType.arguments.single().type!!.asTypeName() + + return TypeInfo(fieldType, packetContainer.member(structureModifierName)) } - val types = mapOf>( - "byte" to get(PacketContainer::getBytes), - "boolean" to get(PacketContainer::getBooleans), - "short" to get(PacketContainer::getShorts), - "int" to get(PacketContainer::getIntegers), - "long" to get(PacketContainer::getLongs), - "float" to get(PacketContainer::getFloat), - "double" to get(PacketContainer::getDoubles), - "java.lang.String" to get(PacketContainer::getStrings), - "java.util.UUID" to get(PacketContainer::getUUIDs), - //TODO doesnt work because Array gets type erased -// "java.lang.String[]" to get>(PacketContainer::getStringArrays), - "byte[]" to get(PacketContainer::getByteArrays), - "int[]" to get(PacketContainer::getIntegerArrays), - "short[]" to get(PacketContainer::getShortArrays), -// "" to get(PacketContainer::getItemModifier), -// "" to get(PacketContainer::getItemArrayModifier), -// "" to get(PacketContainer::getItemListModifier), -// "" to get(PacketContainer::getStatisticMaps), -// "" to get(PacketContainer::getWorldTypeModifier), -// "" to get(PacketContainer::getDataWatcherModifier), - "net.minecraft.world.entity.EntityType" to get(PacketContainer::getEntityTypeModifier), - "net.minecraft.core.BlockPos" to get(PacketContainer::getBlockPositionModifier), - //TODO UNSURE - "net.minecraft.network.chat.Component" to get(PacketContainer::getChatComponents), - //TODO figure something out with this modifier, requires world parameter pass -// "net.minecraft.world.entity.Entity" to get(PacketContainer::getEntityModifier), + val packetContainer = PacketContainer::class.asClassName() + + val outerModifier = mapOf, MemberName>( + List::class to packetContainer.member("lists"), +// Optional::class to PacketContainer::getOptionals, + ) + + private val leafModifier = mapOf>( + // Primitives + typeOf() to PacketContainer::getIntegers, + typeOf() to PacketContainer::getBooleans, + typeOf() to PacketContainer::getShorts, + typeOf() to PacketContainer::getIntegers, + typeOf() to PacketContainer::getLongs, + typeOf() to PacketContainer::getFloat, + typeOf() to PacketContainer::getDoubles, + typeOf() to PacketContainer::getStrings, + typeOf() to PacketContainer::getUUIDs, + typeOf>() to PacketContainer::getStringArrays, + typeOf() to PacketContainer::getByteArrays, + typeOf() to PacketContainer::getIntegerArrays, + typeOf() to PacketContainer::getShortArrays, + typeOf() to PacketContainer::getItemModifier, + typeOf>() to PacketContainer::getItemArrayModifier, + typeOf>() to PacketContainer::getItemListModifier, + typeOf>>() to PacketContainer::getStatisticMaps, +// typeOf() to PacketContainer::getWorldTypeModifier, + typeOf() to PacketContainer::getDataWatcherModifier, + typeOf>() to PacketContainer::getEntityTypeModifier, + typeOf() to PacketContainer::getBlockPositionModifier, + typeOf>() to PacketContainer::getBlockEntityTypeModifier, + // TODO getChunkCoordIntPairs + typeOf() to PacketContainer::getNbtModifier, + typeOf>() to PacketContainer::getListNbtModifier, + typeOf() to PacketContainer::getVectors, + typeOf>() to PacketContainer::getAttributeCollectionModifier, + typeOf>() to PacketContainer::getBlockPositionCollectionModifier, + typeOf>>() to PacketContainer::getWatchableCollectionModifier, + typeOf>>() to PacketContainer::getDataValueCollectionModifier, + // blocks + typeOf() to PacketContainer::getBlocks, + typeOf() to PacketContainer::getBlockData, + typeOf>() to PacketContainer::getBlockDataArrays, + //getMultiBlockChangeInfoArrays + typeOf() to PacketContainer::getChatComponents, + typeOf>() to PacketContainer::getChatComponentArrays, + // getServerPings + // getPlayerInfoDataLists + // getProtocols + // getClientCommands + // getChatVisibilities + typeOf() to PacketContainer::getDifficulties, + // getEntityUseActions + // getEnumEntityUseActions + // getGameModes + // getResourcePackStatus + // getPlayerInfoAction + // getPlayerInfoActions + // getTitleActions + // getWorldBorderActions + // getCombatEvents + // getPlayerDigTypes + // getPlayerActions + // getScoreboardActions + // getParticles + // getNewParticles + // getEffectTypes + // getSoundCategories + // ... + typeOf() to PacketContainer::getHands, + typeOf() to PacketContainer::getDirections, + typeOf() to PacketContainer::getChatTypes, + typeOf() to PacketContainer::getMinecraftKeys, + // getDimensions + typeOf() to PacketContainer::getDimensionTypes, + // getMerchantRecipeLists + // ... ) + @OptIn(ExperimentalStdlibApi::class) + private val mappedLeafModifiers = leafModifier.mapKeys { it.key.javaType } } diff --git a/protocolburrito-plugin/build.gradle.kts b/protocolburrito-plugin/build.gradle.kts index 71e117d..2bf3f20 100644 --- a/protocolburrito-plugin/build.gradle.kts +++ b/protocolburrito-plugin/build.gradle.kts @@ -9,3 +9,11 @@ dependencies { compileOnly(idofrontLibs.bundles.idofront.core) implementation(project(":")) } + + +configurations { + runtimeClasspath { + val protocolLib = idofrontLibs.minecraft.plugin.protocollib.get() + exclude(protocolLib.group, protocolLib.name) + } +} diff --git a/protocolburrito-plugin/src/main/resources/paper-plugin.yml b/protocolburrito-plugin/src/main/resources/paper-plugin.yml index 1cd55c9..49d88f5 100644 --- a/protocolburrito-plugin/src/main/resources/paper-plugin.yml +++ b/protocolburrito-plugin/src/main/resources/paper-plugin.yml @@ -16,3 +16,4 @@ dependencies: ProtocolLib: required: true load: BEFORE + join-classpath: true diff --git a/settings.gradle.kts b/settings.gradle.kts index 345acc6..fd19a73 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,6 +35,7 @@ dependencyResolutionManagement { } include( + "protocolburrito-generator-obfuscated", "protocolburrito-generator", "protocolburrito-api", "protocolburrito-plugin"