Add ClientRequest packet
This commit is contained in:
parent
5c352a5591
commit
32b83a7e60
9 changed files with 66 additions and 14 deletions
|
@ -39,6 +39,7 @@ abstract class EventEmitter<E: Event> {
|
||||||
): EventHandler<T> {
|
): EventHandler<T> {
|
||||||
lateinit var handler: EventHandler<T>
|
lateinit var handler: EventHandler<T>
|
||||||
|
|
||||||
|
@Suppress("JoinDeclarationAndAssignment") // false positive
|
||||||
handler = on(eventType, handlerPosition) {
|
handler = on(eventType, handlerPosition) {
|
||||||
fn(it, handler::remove)
|
fn(it, handler::remove)
|
||||||
}
|
}
|
||||||
|
@ -56,12 +57,21 @@ abstract class EventEmitter<E: Event> {
|
||||||
): EventHandler<T> = onRemovable(eventType, handlerPosition) { event, remove -> remove(); fn(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 ->
|
suspendCancellableCoroutine { c ->
|
||||||
val handler = EventHandler(this, eventType, Plugin.getCalling(), handlerPosition) {
|
lateinit var handler: EventHandler<*>
|
||||||
c.resume(it)
|
|
||||||
|
handler = EventHandler(this, eventType, Plugin.getCalling(), handlerPosition) {
|
||||||
|
if (predicate(it)) {
|
||||||
|
handler.remove()
|
||||||
|
c.resume(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers.add(handler)
|
handlers.add(handler)
|
||||||
|
@ -103,10 +113,13 @@ abstract class EventEmitter<E: Event> {
|
||||||
): EventHandler<T> = once(T::class, handlerPosition, fn)
|
): 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 =
|
suspend inline fun <reified T : E> waitFor(
|
||||||
waitFor(T::class, position)
|
position: EventHandlerPosition = EventHandlerPosition.NORMAL,
|
||||||
|
noinline predicate: (event: T) -> Boolean = { true }
|
||||||
|
): T =
|
||||||
|
waitFor(T::class, position, predicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class EventBus: EventEmitter<Event>() {
|
abstract class EventBus: EventEmitter<Event>() {
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ object PlayProtocol : Protocol(
|
||||||
"PLAY",
|
"PLAY",
|
||||||
ChunkDataPacketCodec,
|
ChunkDataPacketCodec,
|
||||||
ChunkLightDataPacketCodec,
|
ChunkLightDataPacketCodec,
|
||||||
|
ClientRequestPacketCodec,
|
||||||
ClientSettingsPacketCodec,
|
ClientSettingsPacketCodec,
|
||||||
CompassTargetPacketCodec,
|
CompassTargetPacketCodec,
|
||||||
DeclareCommandsPacketCodec,
|
DeclareCommandsPacketCodec,
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,13 +207,11 @@ class LoginAndJoinProcedure(val session: UranosSession) {
|
||||||
session.scheduleKeepAlivePacket(true)
|
session.scheduleKeepAlivePacket(true)
|
||||||
|
|
||||||
player.spawnInitially(state.world)
|
player.spawnInitially(state.world)
|
||||||
|
session.state = Session.State.Playing(player)
|
||||||
player.sendChunksAndLight()
|
player.sendChunksAndLight()
|
||||||
|
|
||||||
// WorldBorder
|
// WorldBorder
|
||||||
session.send(CompassTargetPacket(player.compassTarget))
|
session.send(CompassTargetPacket(player.compassTarget))
|
||||||
session.send(OutgoingPlayerPositionPacket(state.position))
|
session.send(OutgoingPlayerPositionPacket(state.position))
|
||||||
|
|
||||||
// TODO: Wait for ClientStatus(action=0) packet
|
|
||||||
session.state = Session.State.Playing(player)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,8 @@ class UranosSession(val channel: io.netty.channel.Channel, val server: UranosSer
|
||||||
override var ping: Int = -1
|
override var ping: Int = -1
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field == -1) {
|
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) } }
|
scope.launch { server.players.forEach { it.session.send(packet) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
|
|
||||||
package space.uranos.net.packet.login
|
package space.uranos.net.packet.login
|
||||||
|
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import space.uranos.net.PacketReceivedEventHandler
|
import space.uranos.net.PacketReceivedEventHandler
|
||||||
import space.uranos.net.UranosSession
|
import space.uranos.net.UranosSession
|
||||||
|
|
||||||
object EncryptionResponsePacketHandler : PacketReceivedEventHandler<EncryptionResponsePacket>() {
|
object EncryptionResponsePacketHandler : PacketReceivedEventHandler<EncryptionResponsePacket>() {
|
||||||
override suspend fun handle(session: UranosSession, packet: EncryptionResponsePacket) {
|
override suspend fun handle(session: UranosSession, packet: EncryptionResponsePacket) {
|
||||||
try {
|
try {
|
||||||
session.joinProcedure.onEncryptionResponse(packet)
|
session.scope.launch { session.joinProcedure.onEncryptionResponse(packet) }
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
session.failAndDisconnectBecauseOfClient("Client sent EncryptionResponsePacket when it was not allowed.")
|
session.failAndDisconnectBecauseOfClient("Client sent EncryptionResponsePacket when it was not allowed.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
|
|
||||||
package space.uranos.net.packet.login
|
package space.uranos.net.packet.login
|
||||||
|
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import space.uranos.net.PacketReceivedEventHandler
|
import space.uranos.net.PacketReceivedEventHandler
|
||||||
import space.uranos.net.UranosSession
|
import space.uranos.net.UranosSession
|
||||||
|
|
||||||
object LoginStartPacketHandler : PacketReceivedEventHandler<LoginStartPacket>() {
|
object LoginStartPacketHandler : PacketReceivedEventHandler<LoginStartPacket>() {
|
||||||
override suspend fun handle(session: UranosSession, packet: LoginStartPacket) {
|
override suspend fun handle(session: UranosSession, packet: LoginStartPacket) {
|
||||||
try {
|
try {
|
||||||
session.joinProcedure.start(packet)
|
session.scope.launch { session.joinProcedure.start(packet) }
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
session.failAndDisconnectBecauseOfClient("Client sent LoginStartPacket when it was not allowed")
|
session.failAndDisconnectBecauseOfClient("Client sent LoginStartPacket when it was not allowed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
package space.uranos.net.packet.play
|
package space.uranos.net.packet.play
|
||||||
|
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import space.uranos.net.PacketReceivedEventHandler
|
import space.uranos.net.PacketReceivedEventHandler
|
||||||
import space.uranos.net.UranosSession
|
import space.uranos.net.UranosSession
|
||||||
import space.uranos.player.UranosPlayer
|
import space.uranos.player.UranosPlayer
|
||||||
|
@ -16,7 +17,7 @@ object ClientSettingsPacketHandler : PacketReceivedEventHandler<ClientSettingsPa
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
try {
|
try {
|
||||||
session.joinProcedure.onClientSettingsReceived(packet)
|
session.scope.launch { session.joinProcedure.onClientSettingsReceived(packet) }
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
session.failAndDisconnectBecauseOfClient("Client sent ClientSettingsPacket when it was not allowed")
|
session.failAndDisconnectBecauseOfClient("Client sent ClientSettingsPacket when it was not allowed")
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue