use basalt_derive::{Decode, Encode, EncodedSize, packet};
use basalt_types::Decode as _;
use basalt_types::Uuid;
use crate::error::{Error, Result};
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x01)]
pub struct ServerboundLoginEncryptionBegin {
#[field(length = "varint")]
pub shared_secret: Vec<u8>,
#[field(length = "varint")]
pub verify_token: Vec<u8>,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x03)]
pub struct ServerboundLoginLoginAcknowledged;
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x02)]
pub struct ServerboundLoginLoginPluginResponse {
#[field(varint)]
pub message_id: i32,
#[field(optional)]
pub data: Option<Vec<u8>>,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x00)]
pub struct ServerboundLoginLoginStart {
pub username: String,
pub player_uuid: Uuid,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x03)]
pub struct ClientboundLoginCompress {
#[field(varint)]
pub threshold: i32,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x00)]
pub struct ClientboundLoginDisconnect {
pub reason: String,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x01)]
pub struct ClientboundLoginEncryptionBegin {
pub server_id: String,
#[field(length = "varint")]
pub public_key: Vec<u8>,
#[field(length = "varint")]
pub verify_token: Vec<u8>,
pub should_authenticate: bool,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x04)]
pub struct ClientboundLoginLoginPluginRequest {
#[field(varint)]
pub message_id: i32,
pub channel: String,
#[field(rest)]
pub data: Vec<u8>,
}
#[derive(Debug, Clone, Default, PartialEq, Encode, Decode, EncodedSize)]
pub struct ClientboundLoginSuccessProperties {
pub name: String,
pub value: String,
#[field(optional)]
pub signature: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq)]
#[packet(id = 0x02)]
pub struct ClientboundLoginSuccess {
pub uuid: Uuid,
pub username: String,
#[field(length = "varint")]
pub properties: Vec<ClientboundLoginSuccessProperties>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ServerboundLoginPacket {
EncryptionBegin(ServerboundLoginEncryptionBegin),
LoginAcknowledged(ServerboundLoginLoginAcknowledged),
LoginPluginResponse(ServerboundLoginLoginPluginResponse),
LoginStart(ServerboundLoginLoginStart),
}
impl ServerboundLoginPacket {
pub fn decode_by_id(id: i32, buf: &mut &[u8]) -> Result<Self> {
match id {
ServerboundLoginEncryptionBegin::PACKET_ID => Ok(Self::EncryptionBegin(
ServerboundLoginEncryptionBegin::decode(buf)?,
)),
ServerboundLoginLoginAcknowledged::PACKET_ID => Ok(Self::LoginAcknowledged(
ServerboundLoginLoginAcknowledged::decode(buf)?,
)),
ServerboundLoginLoginPluginResponse::PACKET_ID => Ok(Self::LoginPluginResponse(
ServerboundLoginLoginPluginResponse::decode(buf)?,
)),
ServerboundLoginLoginStart::PACKET_ID => {
Ok(Self::LoginStart(ServerboundLoginLoginStart::decode(buf)?))
}
_ => Err(Error::UnknownPacket { id, state: "login" }),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ClientboundLoginPacket {
Compress(ClientboundLoginCompress),
Disconnect(ClientboundLoginDisconnect),
EncryptionBegin(ClientboundLoginEncryptionBegin),
LoginPluginRequest(ClientboundLoginLoginPluginRequest),
Success(ClientboundLoginSuccess),
}
impl ClientboundLoginPacket {
pub fn decode_by_id(id: i32, buf: &mut &[u8]) -> Result<Self> {
match id {
ClientboundLoginCompress::PACKET_ID => {
Ok(Self::Compress(ClientboundLoginCompress::decode(buf)?))
}
ClientboundLoginDisconnect::PACKET_ID => {
Ok(Self::Disconnect(ClientboundLoginDisconnect::decode(buf)?))
}
ClientboundLoginEncryptionBegin::PACKET_ID => Ok(Self::EncryptionBegin(
ClientboundLoginEncryptionBegin::decode(buf)?,
)),
ClientboundLoginLoginPluginRequest::PACKET_ID => Ok(Self::LoginPluginRequest(
ClientboundLoginLoginPluginRequest::decode(buf)?,
)),
ClientboundLoginSuccess::PACKET_ID => {
Ok(Self::Success(ClientboundLoginSuccess::decode(buf)?))
}
_ => Err(Error::UnknownPacket { id, state: "login" }),
}
}
}