Give each entity an UID and make entity classes open
This commit is contained in:
parent
3dc596252d
commit
3fb9cc3298
11 changed files with 39 additions and 37 deletions
|
@ -78,6 +78,7 @@ class EntitiesGenerator(
|
||||||
|
|
||||||
val type = TypeSpec.classBuilder(name)
|
val type = TypeSpec.classBuilder(name)
|
||||||
.superclass(ENTITY_TYPE)
|
.superclass(ENTITY_TYPE)
|
||||||
|
.addModifiers(KModifier.OPEN)
|
||||||
.addProperty(
|
.addProperty(
|
||||||
PropertySpec.builder("type", ENTITY_TYPE_TYPE, KModifier.OVERRIDE, KModifier.FINAL)
|
PropertySpec.builder("type", ENTITY_TYPE_TYPE, KModifier.OVERRIDE, KModifier.FINAL)
|
||||||
.initializer("Type")
|
.initializer("Type")
|
||||||
|
|
|
@ -1,10 +1,2 @@
|
||||||
# suppress inspection "UnusedProperty" for whole file
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
version.kotlin=1.4.20
|
|
||||||
version.netty=4.1.54.Final
|
|
||||||
version.moshi=1.11.0
|
|
||||||
version.kotlinx-coroutines=1.4.2
|
|
||||||
version.slf4j=1.7.30
|
|
||||||
version.junit=5.7.0
|
|
||||||
version.strikt=0.28.0
|
|
||||||
version.guava=30.0-jre
|
|
||||||
|
|
|
@ -5,13 +5,24 @@
|
||||||
|
|
||||||
package space.uranos.entity
|
package space.uranos.entity
|
||||||
|
|
||||||
import space.uranos.Location
|
import space.uranos.Uranos
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
abstract class Entity internal constructor() {
|
abstract class Entity internal constructor() {
|
||||||
val uuid: UUID = UUID.randomUUID()
|
/**
|
||||||
|
* An integer unique to this entity which will not be persisted, for example when the entity is serialized.
|
||||||
|
*/
|
||||||
|
val uid: Int = Uranos.claimEntityID()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID of this entity.
|
||||||
|
*
|
||||||
|
* If the entity is a player and the server uses authentication, it is the player's UUID, if it is not,
|
||||||
|
* it is a UUIDv3 generated from a string consisting of "OfflinePlayer:" and the player's username.
|
||||||
|
*
|
||||||
|
* Otherwise, it is usually randomly generated.
|
||||||
|
*/
|
||||||
|
open val uuid: UUID = UUID.randomUUID()
|
||||||
|
|
||||||
abstract val type: EntityType
|
abstract val type: EntityType
|
||||||
val globallyUniqueNumericID: Int = 0 // TODO: Get a real value
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ package space.uranos.entity
|
||||||
|
|
||||||
import space.uranos.Position
|
import space.uranos.Position
|
||||||
|
|
||||||
class ItemEntity(override var position: Position) : ObjectEntity() {
|
open class ItemEntity(override var position: Position) : ObjectEntity() {
|
||||||
override val type: EntityType = Type
|
final override val type: EntityType = Type
|
||||||
|
|
||||||
companion object Type : ItemEntityType()
|
companion object Type : ItemEntityType()
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,13 @@ interface Server {
|
||||||
val developmentMode: Boolean
|
val developmentMode: Boolean
|
||||||
val minimumLogLevel: Logger.Level
|
val minimumLogLevel: Logger.Level
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an unused entity ID.
|
||||||
|
*
|
||||||
|
* **Should not be used by plugins.**
|
||||||
|
*/
|
||||||
|
fun claimEntityID(): Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiates shutting down the server.
|
* Initiates shutting down the server.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -67,10 +67,7 @@ object ChunkDataPacketCodec : OutgoingPacketCodec<ChunkDataPacket>(0x20, ChunkDa
|
||||||
// Blocks
|
// Blocks
|
||||||
val dataBuf = Unpooled.buffer() // TODO: Set an initial capacity
|
val dataBuf = Unpooled.buffer() // TODO: Set an initial capacity
|
||||||
for (section in data.sections.filterNotNull()) {
|
for (section in data.sections.filterNotNull()) {
|
||||||
val ids = section.map {
|
val ids = section.map { it.material().codec.getStateID(it) }.toIntArray()
|
||||||
println(it)
|
|
||||||
it.material().codec.getStateID(it)
|
|
||||||
}.toIntArray()
|
|
||||||
dataBuf.writeShort(ids.count { !(it == AirBlock.codec.id || it == CaveAirBlock.codec.id) })
|
dataBuf.writeShort(ids.count { !(it == AirBlock.codec.id || it == CaveAirBlock.codec.id) })
|
||||||
dataBuf.writeByte(numberOfBitsPerBlock)
|
dataBuf.writeByte(numberOfBitsPerBlock)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
package space.uranos.net.packet.play
|
package space.uranos.net.packet.play
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
import space.uranos.Difficulty
|
|
||||||
import space.uranos.entity.LivingEntity
|
import space.uranos.entity.LivingEntity
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
||||||
|
@ -30,7 +29,7 @@ object SpawnLivingEntityPacketCodec : OutgoingPacketCodec<SpawnLivingEntityPacke
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPacketFromEntity(entity: LivingEntity) = SpawnLivingEntityPacket(
|
fun getPacketFromEntity(entity: LivingEntity) = SpawnLivingEntityPacket(
|
||||||
entity.globallyUniqueNumericID,
|
entity.uid,
|
||||||
entity.uuid,
|
entity.uuid,
|
||||||
entity.type,
|
entity.type,
|
||||||
entity.position,
|
entity.position,
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
package space.uranos.net.packet.play
|
package space.uranos.net.packet.play
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
import space.uranos.entity.Entity
|
|
||||||
import space.uranos.entity.ItemEntity
|
import space.uranos.entity.ItemEntity
|
||||||
import space.uranos.entity.ObjectEntity
|
import space.uranos.entity.ObjectEntity
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
||||||
import space.uranos.net.packet.OutgoingPacketCodec
|
import space.uranos.net.packet.OutgoingPacketCodec
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
|
|
||||||
object SpawnObjectEntityPacketCodec : OutgoingPacketCodec<SpawnObjectEntityPacket>(0x00, SpawnObjectEntityPacket::class) {
|
object SpawnObjectEntityPacketCodec : OutgoingPacketCodec<SpawnObjectEntityPacket>(0x00, SpawnObjectEntityPacket::class) {
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
|
@ -32,7 +30,7 @@ object SpawnObjectEntityPacketCodec : OutgoingPacketCodec<SpawnObjectEntityPacke
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPacketFromEntity(entity: ObjectEntity) = SpawnObjectEntityPacket(
|
fun getPacketFromEntity(entity: ObjectEntity) = SpawnObjectEntityPacket(
|
||||||
entity.globallyUniqueNumericID,
|
entity.uid,
|
||||||
entity.uuid,
|
entity.uuid,
|
||||||
entity.type,
|
entity.type,
|
||||||
entity.position,
|
entity.position,
|
||||||
|
|
|
@ -7,14 +7,12 @@ package space.uranos.net.packet.play
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
import space.uranos.CardinalDirection
|
import space.uranos.CardinalDirection
|
||||||
import space.uranos.Difficulty
|
|
||||||
import space.uranos.entity.PaintingEntity
|
import space.uranos.entity.PaintingEntity
|
||||||
import space.uranos.entity.PaintingMotive
|
import space.uranos.entity.PaintingMotive
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
||||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVoxelLocation
|
import space.uranos.net.MinecraftProtocolDataTypes.writeVoxelLocation
|
||||||
import space.uranos.net.packet.OutgoingPacketCodec
|
import space.uranos.net.packet.OutgoingPacketCodec
|
||||||
import space.uranos.world.Voxel
|
|
||||||
import space.uranos.world.VoxelLocation
|
import space.uranos.world.VoxelLocation
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
|
@ -33,7 +31,7 @@ object SpawnPaintingPacketCodec : OutgoingPacketCodec<SpawnPaintingPacket>(0x03,
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPacketFromEntity(entity: PaintingEntity) = SpawnPaintingPacket(
|
fun getPacketFromEntity(entity: PaintingEntity) = SpawnPaintingPacket(
|
||||||
entity.globallyUniqueNumericID,
|
entity.uid,
|
||||||
entity.uuid,
|
entity.uuid,
|
||||||
entity.motive,
|
entity.motive,
|
||||||
getCenterLocation(entity.topLeftLocation, entity.motive),
|
getCenterLocation(entity.topLeftLocation, entity.motive),
|
||||||
|
|
|
@ -28,6 +28,7 @@ import space.uranos.world.Dimension
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
@ -89,6 +90,15 @@ class UranosServer internal constructor() : Server {
|
||||||
override val eventBus = UranosEventBus(developmentMode)
|
override val eventBus = UranosEventBus(developmentMode)
|
||||||
override val eventHandlerPositions = UranosEventHandlerPositionManager()
|
override val eventHandlerPositions = UranosEventHandlerPositionManager()
|
||||||
|
|
||||||
|
private val nextEntityID = AtomicInteger()
|
||||||
|
override fun claimEntityID() = nextEntityID.incrementAndGet()
|
||||||
|
|
||||||
|
override fun shutdown() {
|
||||||
|
runBlocking {
|
||||||
|
scheduler.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun failInitialization(t: Throwable): Nothing {
|
private fun failInitialization(t: Throwable): Nothing {
|
||||||
logger.error("Server initialization failed:", t)
|
logger.error("Server initialization failed:", t)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
|
@ -107,12 +117,6 @@ class UranosServer internal constructor() : Server {
|
||||||
scheduler.startTicking()
|
scheduler.startTicking()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shutdown() {
|
|
||||||
runBlocking {
|
|
||||||
scheduler.shutdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val VERSION = UranosServer::class.java.`package`.implementationVersion ?: "development"
|
val VERSION = UranosServer::class.java.`package`.implementationVersion ?: "development"
|
||||||
val VERSION_WITH_V = if (VERSION == "development") VERSION else "v$VERSION"
|
val VERSION_WITH_V = if (VERSION == "development") VERSION else "v$VERSION"
|
||||||
|
|
|
@ -60,14 +60,9 @@ class EventBusTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
val actualOrder = (Uranos.eventHandlerPositions as UranosEventHandlerPositionManager).positions
|
val actualOrder = (Uranos.eventHandlerPositions as UranosEventHandlerPositionManager).positions
|
||||||
println(actualOrder)
|
|
||||||
|
|
||||||
Uranos.eventHandlerPositions.insertAfter(EventHandlerPosition.FIRST, Position1, Position5)
|
Uranos.eventHandlerPositions.insertAfter(EventHandlerPosition.FIRST, Position1, Position5)
|
||||||
println(actualOrder)
|
|
||||||
Uranos.eventHandlerPositions.insertBefore(Position1, Position2, Position4)
|
Uranos.eventHandlerPositions.insertBefore(Position1, Position2, Position4)
|
||||||
println(actualOrder)
|
|
||||||
Uranos.eventHandlerPositions.insert(Position3, Position6)
|
Uranos.eventHandlerPositions.insert(Position3, Position6)
|
||||||
println(actualOrder)
|
|
||||||
|
|
||||||
actualOrder.forEachIndexed { index, position ->
|
actualOrder.forEachIndexed { index, position ->
|
||||||
expectThat(index).isEqualTo(expectedOrder.indexOf(position))
|
expectThat(index).isEqualTo(expectedOrder.indexOf(position))
|
||||||
|
|
Reference in a new issue