Archived
1
0
Fork 0

Add ClientRequest packet

This commit is contained in:
Moritz Ruth 2021-01-08 19:21:24 +01:00
parent 5c352a5591
commit 32b83a7e60
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
9 changed files with 66 additions and 14 deletions

View file

@ -39,6 +39,7 @@ abstract class EventEmitter<E: Event> {
): EventHandler<T> {
lateinit var handler: EventHandler<T>
@Suppress("JoinDeclarationAndAssignment") // false positive
handler = on(eventType, handlerPosition) {
fn(it, handler::remove)
}
@ -56,12 +57,21 @@ abstract class EventEmitter<E: Event> {
): EventHandler<T> = onRemovable(eventType, handlerPosition) { event, remove -> remove(); fn(event) }
/**
* Suspends until an event of type [T] is emitted and returns it.
* Suspends until an event of type [T] is emitted for which [predicate] returns true and returns it.
*/
suspend fun <T: E> waitFor(eventType: KClass<T>, handlerPosition: EventHandlerPosition = EventHandlerPosition.NORMAL): T =
suspend fun <T : E> waitFor(
eventType: KClass<T>,
handlerPosition: EventHandlerPosition = EventHandlerPosition.NORMAL,
predicate: (event: T) -> Boolean = { true }
): T =
suspendCancellableCoroutine { c ->
val handler = EventHandler(this, eventType, Plugin.getCalling(), handlerPosition) {
c.resume(it)
lateinit var handler: EventHandler<*>
handler = EventHandler(this, eventType, Plugin.getCalling(), handlerPosition) {
if (predicate(it)) {
handler.remove()
c.resume(it)
}
}
handlers.add(handler)
@ -103,10 +113,13 @@ abstract class EventEmitter<E: Event> {
): EventHandler<T> = once(T::class, handlerPosition, fn)
/**
* Suspends until an event of type [T] is emitted and returns it.
* Suspends until an event of type [T] is emitted for which [predicate] returns true and returns it.
*/
suspend inline fun <reified T: E> waitFor(position: EventHandlerPosition = EventHandlerPosition.NORMAL): T =
waitFor(T::class, position)
suspend inline fun <reified T : E> waitFor(
position: EventHandlerPosition = EventHandlerPosition.NORMAL,
noinline predicate: (event: T) -> Boolean = { true }
): T =
waitFor(T::class, position, predicate)
}
abstract class EventBus: EventEmitter<Event>() {

View file

@ -0,0 +1,21 @@
/*
* Copyright 2020-2021 Moritz Ruth and Uranos contributors
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
*/
package space.uranos.net.packet.play
import io.netty.buffer.ByteBuf
import space.uranos.net.MinecraftProtocolDataTypes.readVarInt
import space.uranos.net.packet.IncomingPacketCodec
object ClientRequestPacketCodec :
IncomingPacketCodec<ClientRequestPacket>(0x04, ClientRequestPacket::class) {
override fun decode(msg: ByteBuf): ClientRequestPacket = ClientRequestPacket(
when (msg.readVarInt()) {
0 -> ClientRequestPacket.Type.PERFORM_RESPAWN
1 -> ClientRequestPacket.Type.STATS
else -> throw Exception("Unknown client request type")
}
)
}

View file

@ -11,6 +11,7 @@ object PlayProtocol : Protocol(
"PLAY",
ChunkDataPacketCodec,
ChunkLightDataPacketCodec,
ClientRequestPacketCodec,
ClientSettingsPacketCodec,
CompassTargetPacketCodec,
DeclareCommandsPacketCodec,

View file

@ -0,0 +1,15 @@
/*
* Copyright 2020-2021 Moritz Ruth and Uranos contributors
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
*/
package space.uranos.net.packet.play
import space.uranos.net.packet.IncomingPacket
data class ClientRequestPacket(val type: Type) : IncomingPacket() {
enum class Type {
PERFORM_RESPAWN,
STATS
}
}

View file

@ -207,13 +207,11 @@ class LoginAndJoinProcedure(val session: UranosSession) {
session.scheduleKeepAlivePacket(true)
player.spawnInitially(state.world)
session.state = Session.State.Playing(player)
player.sendChunksAndLight()
// WorldBorder
session.send(CompassTargetPacket(player.compassTarget))
session.send(OutgoingPlayerPositionPacket(state.position))
// TODO: Wait for ClientStatus(action=0) packet
session.state = Session.State.Playing(player)
}
}

View file

@ -44,7 +44,8 @@ class UranosSession(val channel: io.netty.channel.Channel, val server: UranosSer
override var ping: Int = -1
set(value) {
if (field == -1) {
val packet = PlayerInfoPacket(PlayerInfoPacket.Action.UpdateLatency(mapOf(player!!.uuid to value)))
val packet =
PlayerInfoPacket(PlayerInfoPacket.Action.UpdateLatency(mapOf((state as State.WithPlayer).player.uuid to value)))
scope.launch { server.players.forEach { it.session.send(packet) } }
}

View file

@ -5,13 +5,14 @@
package space.uranos.net.packet.login
import kotlinx.coroutines.launch
import space.uranos.net.PacketReceivedEventHandler
import space.uranos.net.UranosSession
object EncryptionResponsePacketHandler : PacketReceivedEventHandler<EncryptionResponsePacket>() {
override suspend fun handle(session: UranosSession, packet: EncryptionResponsePacket) {
try {
session.joinProcedure.onEncryptionResponse(packet)
session.scope.launch { session.joinProcedure.onEncryptionResponse(packet) }
} catch (e: IllegalStateException) {
session.failAndDisconnectBecauseOfClient("Client sent EncryptionResponsePacket when it was not allowed.")
}

View file

@ -5,13 +5,14 @@
package space.uranos.net.packet.login
import kotlinx.coroutines.launch
import space.uranos.net.PacketReceivedEventHandler
import space.uranos.net.UranosSession
object LoginStartPacketHandler : PacketReceivedEventHandler<LoginStartPacket>() {
override suspend fun handle(session: UranosSession, packet: LoginStartPacket) {
try {
session.joinProcedure.start(packet)
session.scope.launch { session.joinProcedure.start(packet) }
} catch (e: IllegalStateException) {
session.failAndDisconnectBecauseOfClient("Client sent LoginStartPacket when it was not allowed")
}

View file

@ -5,6 +5,7 @@
package space.uranos.net.packet.play
import kotlinx.coroutines.launch
import space.uranos.net.PacketReceivedEventHandler
import space.uranos.net.UranosSession
import space.uranos.player.UranosPlayer
@ -16,7 +17,7 @@ object ClientSettingsPacketHandler : PacketReceivedEventHandler<ClientSettingsPa
if (player == null) {
try {
session.joinProcedure.onClientSettingsReceived(packet)
session.scope.launch { session.joinProcedure.onClientSettingsReceived(packet) }
} catch (e: IllegalStateException) {
session.failAndDisconnectBecauseOfClient("Client sent ClientSettingsPacket when it was not allowed")
}