Archived
1
0
Fork 0

Add Tags packet and send it during join procedure

This commit is contained in:
Moritz Ruth 2020-11-30 18:10:02 +01:00
parent d387842f95
commit aa4f1d89f5
14 changed files with 153 additions and 42 deletions

View file

@ -42,6 +42,10 @@ dependencies {
kotlin {
sourceSets["main"].kotlin.srcDir("src/main/generatedKotlin")
sourceSets.all {
languageSettings.enableLanguageFeature("InlineClasses")
}
}
tasks {

View file

@ -0,0 +1,6 @@
package space.blokk
inline class NamespacedID(val value: String) {
val namespace get() = value.substringBefore(":")
val id get() = value.substringAfter(":")
}

View file

@ -0,0 +1,6 @@
package space.blokk.recipe
sealed class Recipe {
abstract val group: String
// TODO
}

View file

@ -9,6 +9,7 @@ import space.blokk.logging.LoggingOutputProvider
import space.blokk.net.Session
import space.blokk.player.Player
import space.blokk.plugin.PluginManager
import space.blokk.recipe.Recipe
import space.blokk.server.event.ServerEvent
import java.io.File
@ -31,6 +32,8 @@ interface Server : EventTarget<ServerEvent> {
val minimumLogLevel: Logger.Level
val loggingOutputProvider: LoggingOutputProvider
val recipes: Set<Recipe>
/**
* Creates a [ReceiveChannel] which emits [Unit] every tick.
*

View file

@ -1,11 +1,17 @@
package space.blokk.tags
import space.blokk.NamespacedID
import space.blokk.world.block.Material
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)
}
val values: List<NamespacedID> = rawValues.flatMap {
if (it.startsWith("#")) TagRegistry.tags.getValue(it.removePrefix("#")).values
else listOf(NamespacedID(it))
}
val numericIDs: List<Int> = when (type) {
Type.BLOCKS -> values.map { Material.byID.getValue(it).numericID }
else -> TODO()
}
enum class Type {

View file

@ -0,0 +1,14 @@
package space.blokk.net.packet.play
import io.netty.buffer.ByteBuf
import space.blokk.net.MinecraftProtocolDataTypes.writeVarInt
import space.blokk.net.packet.OutgoingPacketCodec
object DeclareRecipesPacketCodec : OutgoingPacketCodec<DeclareRecipesPacket>(0x5B, DeclareRecipesPacket::class) {
override fun DeclareRecipesPacket.encode(dst: ByteBuf) {
dst.writeVarInt(recipes.size)
for (recipe in recipes) {
// TODO
}
}
}

View file

@ -5,6 +5,7 @@ import space.blokk.net.packet.Protocol
object PlayProtocol : Protocol(
"PLAY",
ClientSettingsPacketCodec,
DeclareRecipesPacketCodec,
DisconnectPacketCodec,
IncomingPluginMessagePacketCodec,
JoinGamePacketCodec,
@ -14,5 +15,6 @@ object PlayProtocol : Protocol(
PlayerPositionAndLookPacketCodec,
ServerDifficultyPacketCodec,
SetSelectedHotbarSlotPacketCodec,
TagsPacketCodec,
UpdateViewPositionPacketCodec
)

View file

@ -0,0 +1,26 @@
package space.blokk.net.packet.play
import io.netty.buffer.ByteBuf
import space.blokk.net.MinecraftProtocolDataTypes.writeString
import space.blokk.net.MinecraftProtocolDataTypes.writeVarInt
import space.blokk.net.packet.OutgoingPacketCodec
import space.blokk.tags.Tag
object TagsPacketCodec : OutgoingPacketCodec<TagsPacket>(0x5C, TagsPacket::class) {
override fun TagsPacket.encode(dst: ByteBuf) {
listOf(
tags.filter { it.type == Tag.Type.BLOCKS },
tags.filter { it.type == Tag.Type.ITEMS },
tags.filter { it.type == Tag.Type.FLUIDS },
tags.filter { it.type == Tag.Type.ENTITY_TYPES }
).forEach { tags ->
dst.writeVarInt(tags.size)
tags.forEach { tag ->
dst.writeString(tag.name)
dst.writeVarInt(tag.values.size)
tag.numericIDs.forEach { dst.writeVarInt(it) }
}
}
}
}

View file

@ -0,0 +1,9 @@
package space.blokk.net.packet.play
import space.blokk.net.packet.OutgoingPacket
import space.blokk.recipe.Recipe
/**
* Sent by the server while the player is joining.
*/
data class DeclareRecipesPacket(val recipes: Set<Recipe>) : OutgoingPacket()

View file

@ -0,0 +1,9 @@
package space.blokk.net.packet.play
import space.blokk.net.packet.OutgoingPacket
import space.blokk.tags.Tag
/**
* Sent by the server while the player is joining.
*/
data class TagsPacket(val tags: Iterable<Tag>) : OutgoingPacket()

View file

@ -11,6 +11,7 @@ import space.blokk.logging.Logger
import space.blokk.net.BlokkSocketServer
import space.blokk.player.Player
import space.blokk.plugin.BlokkPluginManager
import space.blokk.recipe.Recipe
import space.blokk.server.Server
import space.blokk.server.event.ServerEvent
import space.blokk.util.EncryptionUtils
@ -18,6 +19,7 @@ import space.blokk.util.Ticker
import space.blokk.util.createUnconfinedSupervisorScope
import java.io.File
import java.security.KeyPair
import java.util.concurrent.CopyOnWriteArraySet
import kotlin.system.exitProcess
class BlokkServer internal constructor() : Server {
@ -31,6 +33,8 @@ class BlokkServer internal constructor() : Server {
override val players = EventTargetGroup.Mutable<Player>(true)
override val pluginManager = BlokkPluginManager(this)
override val recipes: Set<Recipe> = CopyOnWriteArraySet()
val keyPair: KeyPair
init {

View file

@ -172,7 +172,7 @@ class LoginAndJoinProcedure(val session: BlokkSession) {
session.send(SetSelectedHotbarSlotPacket(state.selectedHotbarSlot))
// TODO: Send Declare Recipes packet
session.send(DeclareRecipesPacket(session.server.recipes))
// TODO: Send Tags packet
// TODO: Send Entity Status packet with OP permission level

View file

@ -2,10 +2,11 @@ package space.blokk.mdsp
import com.google.common.base.CaseFormat
import com.jsoniter.JsonIterator
import com.jsoniter.ValueType
import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import space.blokk.mdsp.util.ConstructorPropertiesHelper
import java.io.File
import java.util.*
class BlocksAndMaterialGenerator(
private val workingDir: File,
@ -15,6 +16,7 @@ class BlocksAndMaterialGenerator(
companion object {
const val BLOCK_PACKAGE = "space.blokk.world.block"
val MATERIAL_TYPE = ClassName(BLOCK_PACKAGE, "Material")
val NAMESPACED_ID_TYPE = ClassName("space.blokk", "NamespacedID")
val BLOCK_TYPE = ClassName(BLOCK_PACKAGE, "Block")
val K_CLASS_TYPE = ClassName("kotlin.reflect", "KClass")
val MAP_TYPE = ClassName("kotlin.collections", "Map")
@ -111,24 +113,30 @@ class BlocksAndMaterialGenerator(
}
private fun generateMaterialEnum(blocks: List<JsonAny>, collisionShapeKeyByBlockName: MutableMap<String, JsonAny>) {
val cph = ConstructorPropertiesHelper()
val builder = TypeSpec.enumBuilder("Material")
.primaryConstructor(
FunSpec.constructorBuilder()
.addParameter("id", String::class)
.addParameter(
"blockType",
K_CLASS_TYPE.parameterizedBy(WildcardTypeName.producerOf(BLOCK_TYPE))
.addParameters(
listOf(
cph.create("numericID", Int::class),
cph.create("id", NAMESPACED_ID_TYPE),
cph.create(
"blockType",
K_CLASS_TYPE.parameterizedBy(WildcardTypeName.producerOf(BLOCK_TYPE))
),
cph.create("hardness", Float::class),
cph.create("transparent", Boolean::class),
cph.create("emittedLight", Int::class),
cph.create("filteredLight", Int::class),
cph.create("collisionShape", ClassName(BLOCK_PACKAGE, "CollisionShape")),
cph.create("maxStackSize", Byte::class),
)
)
.addParameter("hardness", Float::class)
.addParameter("transparent", Boolean::class)
.addParameter("emittedLight", Byte::class)
.addParameter("filteredLight", Byte::class)
.addParameter("collisionShape", ClassName(BLOCK_PACKAGE, "CollisionShape"))
.addParameter("maxStackSize", Byte::class)
.build()
)
val materialNameByBlockClassName = mutableMapOf<String, String>()
.addProperties(cph.getProperties())
for (block in blocks) {
val name = block.get("name").toString()
@ -136,12 +144,11 @@ class BlocksAndMaterialGenerator(
val materialName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, name)
val blockClassName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name)
materialNameByBlockClassName[blockClassName] = materialName
builder.addEnumConstant(
materialName,
TypeSpec.anonymousClassBuilder()
.addSuperclassConstructorParameter("%S", "minecraft:$name")
.addSuperclassConstructorParameter("%L", block.get("id").toInt())
.addSuperclassConstructorParameter("%T(%S)", NAMESPACED_ID_TYPE, "minecraft:$name")
.addSuperclassConstructorParameter(
"%T::class",
ClassName(
@ -158,11 +165,8 @@ class BlocksAndMaterialGenerator(
ClassName(
BLOCK_PACKAGE,
"CollisionShape",
try {
collisionShapeValue.asList()[0].toString()
} catch (e: Exception) {
collisionShapeValue.toInt().toString()
}
if (collisionShapeValue.valueType() == ValueType.ARRAY) collisionShapeValue.asList()[0].toString()
else collisionShapeValue.toInt().toString()
)
)
.addSuperclassConstructorParameter("%L", block.get("stackSize").toInt())
@ -170,14 +174,6 @@ class BlocksAndMaterialGenerator(
)
}
val initializerTypes = materialNameByBlockClassName.toList()
.flatMap { (blockClassName, materialName) ->
listOf(
ClassName(BLOCK_PACKAGE, blockClassName),
ClassName(BLOCK_PACKAGE, "Material", materialName)
)
}
builder.addType(
TypeSpec.companionObjectBuilder()
.addProperty(
@ -188,14 +184,18 @@ class BlocksAndMaterialGenerator(
MATERIAL_TYPE
)
)
.initializer(
"mapOf(\n" +
arrayOfNulls<String>(materialNameByBlockClassName.size)
.apply { Arrays.fill(this, "%T::class to %T") }
.joinToString(",\n") +
"\n)",
*initializerTypes.toTypedArray()
.initializer("values().map { it.blockType to it }.toMap()")
.build()
)
.addProperty(
PropertySpec.builder(
"byID",
MAP_TYPE.parameterizedBy(
NAMESPACED_ID_TYPE,
MATERIAL_TYPE
)
)
.initializer("values().map { it.id to it }.toMap()")
.build()
)
.build()

View file

@ -0,0 +1,22 @@
package space.blokk.mdsp.util
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeName
import kotlin.reflect.KClass
class ConstructorPropertiesHelper {
private val properties = mutableListOf<PropertySpec>()
fun create(name: String, type: TypeName): ParameterSpec {
properties.add(PropertySpec.builder(name, type).initializer(name).build())
return ParameterSpec.builder(name, type).build()
}
fun create(name: String, type: KClass<*>): ParameterSpec {
properties.add(PropertySpec.builder(name, type).initializer(name).build())
return ParameterSpec.builder(name, type).build()
}
fun getProperties() = properties.toList()
}