Implemented clientbound packet waypoint 0x8a
This commit is contained in:
6 files changed
+175
-1
No files matched your search
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.primitives
|
||||||
|
|
||||||
|
import cn.rtast.libmc.stream.BytesBuffer
|
||||||
|
|
||||||
|
public sealed class Either<out L, out R> {
|
||||||
|
public data class Left<out L>(val value: L) : Either<L, Nothing>()
|
||||||
|
public data class Right<out R>(val value: R) : Either<Nothing, R>()
|
||||||
|
|
||||||
|
public val isLeft: Boolean get() = this is Left
|
||||||
|
public val isRight: Boolean get() = this is Right
|
||||||
|
}
|
||||||
|
|
||||||
|
public suspend inline fun <L, R> BytesBuffer.readEither(
|
||||||
|
readLeft: BytesBuffer.() -> L,
|
||||||
|
readRight: BytesBuffer.() -> R,
|
||||||
|
): Either<L, R> {
|
||||||
|
val isLeft = readBoolean()
|
||||||
|
return if (isLeft) Either.Left(readLeft(this)) else Either.Right(readRight(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
public suspend inline fun <L, R> BytesBuffer.writeEither(
|
||||||
|
either: Either<L, R>,
|
||||||
|
writeLeft: BytesBuffer.(L) -> Unit,
|
||||||
|
writeRight: BytesBuffer.(R) -> Unit,
|
||||||
|
) {
|
||||||
|
when (either) {
|
||||||
|
is Either.Left -> {
|
||||||
|
writeBoolean(true)
|
||||||
|
writeLeft(this, either.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
is Either.Right -> {
|
||||||
|
writeBoolean(false)
|
||||||
|
writeRight(this, either.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.play.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.packet.MinecraftPacket
|
||||||
|
import cn.rtast.libmc.packet.PacketCodec
|
||||||
|
import cn.rtast.libmc.primitives.*
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.Identifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.world.waypoint.WaypointColor
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.world.waypoint.WaypointData
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.world.waypoint.WaypointOperation
|
||||||
|
import cn.rtast.libmc.stream.BytesBuffer
|
||||||
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
public data class ClientboundWaypointPacket(
|
||||||
|
val operation: WaypointOperation,
|
||||||
|
val identifier: Either<Uuid, Identifier>,
|
||||||
|
val iconStyle: Identifier,
|
||||||
|
val waypointColor: WaypointColor?,
|
||||||
|
val waypointData: WaypointData,
|
||||||
|
) : MinecraftPacket {
|
||||||
|
internal companion object Codec : PacketCodec<ClientboundWaypointPacket> {
|
||||||
|
override suspend fun encode(buffer: BytesBuffer, value: ClientboundWaypointPacket) {}
|
||||||
|
override suspend fun decode(buffer: BytesBuffer): ClientboundWaypointPacket {
|
||||||
|
val operation = WaypointOperation.fromID(buffer.readVarInt())
|
||||||
|
val identifier = buffer.readEither(
|
||||||
|
readLeft = { readUuid() },
|
||||||
|
readRight = { readIdentifier() }
|
||||||
|
)
|
||||||
|
val iconStyle = buffer.readIdentifier()
|
||||||
|
val color = buffer.readOptional {
|
||||||
|
val red = readUByte()
|
||||||
|
val green = readUByte()
|
||||||
|
val blue = readUByte()
|
||||||
|
WaypointColor(red, green, blue)
|
||||||
|
}
|
||||||
|
val data = when (WaypointData.Type.fromID(buffer.readVarInt())) {
|
||||||
|
WaypointData.Type.EMPTY -> WaypointData.Empty
|
||||||
|
WaypointData.Type.VEC3I -> {
|
||||||
|
val x = buffer.readVarInt()
|
||||||
|
val y = buffer.readVarInt()
|
||||||
|
val z = buffer.readVarInt()
|
||||||
|
WaypointData.Vec3i(x, y, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
WaypointData.Type.CHUNK -> {
|
||||||
|
val x = buffer.readVarInt()
|
||||||
|
val z = buffer.readVarInt()
|
||||||
|
WaypointData.Chunk(x, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
WaypointData.Type.AZIMUTH -> WaypointData.Azimuth(buffer.readFloat())
|
||||||
|
}
|
||||||
|
return ClientboundWaypointPacket(operation, identifier, iconStyle, color, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -198,7 +198,7 @@ internal object GamePacketsProtocolCodec {
|
|||||||
register(0x87, ClientboundProjectilePowerPacket)
|
register(0x87, ClientboundProjectilePowerPacket)
|
||||||
register(0x88, ClientboundCustomReportDetailsPacket)
|
register(0x88, ClientboundCustomReportDetailsPacket)
|
||||||
register(0x89, ClientboundServerLinksPacket)
|
register(0x89, ClientboundServerLinksPacket)
|
||||||
// register(0x8a, ClientboundWaypointPacket)
|
register(0x8a, ClientboundWaypointPacket)
|
||||||
register(0x8b, ClientboundClearDialogPacket)
|
register(0x8b, ClientboundClearDialogPacket)
|
||||||
register(0x8c, ClientboundShowDialogPacket)
|
register(0x8c, ClientboundShowDialogPacket)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.protocol.game.world.waypoint
|
||||||
|
|
||||||
|
public data class WaypointColor(val red: UByte, val green: UByte, val blue: UByte)
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.protocol.game.world.waypoint
|
||||||
|
|
||||||
|
public sealed class WaypointData {
|
||||||
|
public enum class Type(public val id: Int) {
|
||||||
|
EMPTY(0),
|
||||||
|
VEC3I(1),
|
||||||
|
CHUNK(2),
|
||||||
|
AZIMUTH(3);
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun fromID(id: Int): Type = entries.find { it.id == id } ?: EMPTY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract val type: Type
|
||||||
|
|
||||||
|
public data object Empty : WaypointData() {
|
||||||
|
override val type: Type = Type.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
public data class Vec3i(val x: Int, val y: Int, val z: Int) : WaypointData() {
|
||||||
|
override val type: Type = Type.VEC3I
|
||||||
|
}
|
||||||
|
|
||||||
|
public data class Chunk(val x: Int, val z: Int) : WaypointData() {
|
||||||
|
override val type: Type = Type.CHUNK
|
||||||
|
}
|
||||||
|
|
||||||
|
public data class Azimuth(val angle: Float) : WaypointData() {
|
||||||
|
override val type: Type = Type.AZIMUTH
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.protocol.game.world.waypoint
|
||||||
|
|
||||||
|
public enum class WaypointOperation(public val id: Int) {
|
||||||
|
TRACK(0),
|
||||||
|
UNTRACK(1),
|
||||||
|
UPDATE(2);
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun fromID(id: Int): WaypointOperation = entries.find { it.id == id } ?: TRACK
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user