1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

Merge pull request #13 from mat-1/split-clientbound-serverbound

Split clientbound and serverbound packets
This commit is contained in:
mat 2022-07-30 22:57:02 +00:00 committed by GitHub
commit bc71c74bef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 446 additions and 416 deletions

View file

@ -3,7 +3,7 @@ use azalea_auth::game_profile::GameProfile;
use azalea_core::{ChunkPos, EntityPos, PositionDelta, PositionDeltaTrait, ResourceLocation};
use azalea_entity::Entity;
use azalea_protocol::{
connect::{GameConnection, HandshakeConnection},
connect::Connection,
packets::{
game::{
clientbound_player_chat_packet::ClientboundPlayerChatPacket,
@ -11,13 +11,14 @@ use azalea_protocol::{
serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket,
serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot, GamePacket,
serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot,
ClientboundGamePacket, ServerboundGamePacket,
},
handshake::client_intention_packet::ClientIntentionPacket,
login::{
serverbound_hello_packet::ServerboundHelloPacket,
serverbound_key_packet::{NonceOrSaltSignature, ServerboundKeyPacket},
LoginPacket,
ClientboundLoginPacket,
},
ConnectionProtocol, PROTOCOL_VERSION,
},
@ -60,7 +61,7 @@ pub enum ChatPacket {
#[derive(Clone)]
pub struct Client {
game_profile: GameProfile,
pub conn: Arc<tokio::sync::Mutex<GameConnection>>,
pub conn: Arc<tokio::sync::Mutex<Connection<ClientboundGamePacket, ServerboundGamePacket>>>,
pub player: Arc<Mutex<Player>>,
pub dimension: Arc<Mutex<Option<Dimension>>>,
// game_loop
@ -80,7 +81,7 @@ impl Client {
) -> Result<(Self, UnboundedReceiver<Event>), String> {
let resolved_address = resolver::resolve_address(address).await?;
let mut conn = HandshakeConnection::new(&resolved_address).await?;
let mut conn = Connection::new(&resolved_address).await?;
// handshake
conn.write(
@ -110,7 +111,7 @@ impl Client {
let packet_result = conn.read().await;
match packet_result {
Ok(packet) => match packet {
LoginPacket::ClientboundHelloPacket(p) => {
ClientboundLoginPacket::ClientboundHelloPacket(p) => {
println!("Got encryption request");
let e = azalea_crypto::encrypt(&p.public_key, &p.nonce).unwrap();
@ -128,21 +129,20 @@ impl Client {
.await;
conn.set_encryption_key(e.secret_key);
}
LoginPacket::ClientboundLoginCompressionPacket(p) => {
ClientboundLoginPacket::ClientboundLoginCompressionPacket(p) => {
println!("Got compression request {:?}", p.compression_threshold);
conn.set_compression_threshold(p.compression_threshold);
}
LoginPacket::ClientboundGameProfilePacket(p) => {
ClientboundLoginPacket::ClientboundGameProfilePacket(p) => {
println!("Got profile {:?}", p.game_profile);
break (conn.game(), p.game_profile);
}
LoginPacket::ClientboundLoginDisconnectPacket(p) => {
ClientboundLoginPacket::ClientboundLoginDisconnectPacket(p) => {
println!("Got disconnect {:?}", p);
}
LoginPacket::ClientboundCustomQueryPacket(p) => {
ClientboundLoginPacket::ClientboundCustomQueryPacket(p) => {
println!("Got custom query {:?}", p);
}
_ => panic!("Unexpected packet {:?}", packet),
},
Err(e) => {
panic!("Error: {:?}", e);
@ -203,12 +203,12 @@ impl Client {
}
async fn handle(
packet: &GamePacket,
packet: &ClientboundGamePacket,
client: &Client,
tx: &UnboundedSender<Event>,
) -> Result<(), HandleError> {
match packet {
GamePacket::ClientboundLoginPacket(p) => {
ClientboundGamePacket::ClientboundLoginPacket(p) => {
println!("Got login packet {:?}", p);
{
@ -307,40 +307,40 @@ impl Client {
tx.send(Event::Login).unwrap();
}
GamePacket::ClientboundUpdateViewDistancePacket(p) => {
ClientboundGamePacket::ClientboundUpdateViewDistancePacket(p) => {
println!("Got view distance packet {:?}", p);
}
GamePacket::ClientboundCustomPayloadPacket(p) => {
ClientboundGamePacket::ClientboundCustomPayloadPacket(p) => {
println!("Got custom payload packet {:?}", p);
}
GamePacket::ClientboundChangeDifficultyPacket(p) => {
ClientboundGamePacket::ClientboundChangeDifficultyPacket(p) => {
println!("Got difficulty packet {:?}", p);
}
GamePacket::ClientboundDeclareCommandsPacket(_p) => {
ClientboundGamePacket::ClientboundDeclareCommandsPacket(_p) => {
println!("Got declare commands packet");
}
GamePacket::ClientboundPlayerAbilitiesPacket(p) => {
ClientboundGamePacket::ClientboundPlayerAbilitiesPacket(p) => {
println!("Got player abilities packet {:?}", p);
}
GamePacket::ClientboundSetCarriedItemPacket(p) => {
ClientboundGamePacket::ClientboundSetCarriedItemPacket(p) => {
println!("Got set carried item packet {:?}", p);
}
GamePacket::ClientboundUpdateTagsPacket(_p) => {
ClientboundGamePacket::ClientboundUpdateTagsPacket(_p) => {
println!("Got update tags packet");
}
GamePacket::ClientboundDisconnectPacket(p) => {
ClientboundGamePacket::ClientboundDisconnectPacket(p) => {
println!("Got disconnect packet {:?}", p);
}
GamePacket::ClientboundUpdateRecipesPacket(_p) => {
ClientboundGamePacket::ClientboundUpdateRecipesPacket(_p) => {
println!("Got update recipes packet");
}
GamePacket::ClientboundEntityEventPacket(_p) => {
ClientboundGamePacket::ClientboundEntityEventPacket(_p) => {
// println!("Got entity event packet {:?}", p);
}
GamePacket::ClientboundRecipePacket(_p) => {
ClientboundGamePacket::ClientboundRecipePacket(_p) => {
println!("Got recipe packet");
}
GamePacket::ClientboundPlayerPositionPacket(p) => {
ClientboundGamePacket::ClientboundPlayerPositionPacket(p) => {
// TODO: reply with teleport confirm
println!("Got player position packet {:?}", p);
@ -432,10 +432,10 @@ impl Client {
)
.await;
}
GamePacket::ClientboundPlayerInfoPacket(p) => {
ClientboundGamePacket::ClientboundPlayerInfoPacket(p) => {
println!("Got player info packet {:?}", p);
}
GamePacket::ClientboundSetChunkCacheCenterPacket(p) => {
ClientboundGamePacket::ClientboundSetChunkCacheCenterPacket(p) => {
println!("Got chunk cache center packet {:?}", p);
client
.dimension
@ -444,7 +444,7 @@ impl Client {
.unwrap()
.update_view_center(&ChunkPos::new(p.x, p.z));
}
GamePacket::ClientboundLevelChunkWithLightPacket(p) => {
ClientboundGamePacket::ClientboundLevelChunkWithLightPacket(p) => {
println!("Got chunk with light packet {} {}", p.x, p.z);
let pos = ChunkPos::new(p.x, p.z);
// let chunk = Chunk::read_with_world_height(&mut p.chunk_data);
@ -457,10 +457,10 @@ impl Client {
.replace_with_packet_data(&pos, &mut p.chunk_data.data.as_slice())
.unwrap();
}
GamePacket::ClientboundLightUpdatePacket(p) => {
ClientboundGamePacket::ClientboundLightUpdatePacket(p) => {
println!("Got light update packet {:?}", p);
}
GamePacket::ClientboundAddEntityPacket(p) => {
ClientboundGamePacket::ClientboundAddEntityPacket(p) => {
println!("Got add entity packet {:?}", p);
let entity = Entity::from(p);
client
@ -470,19 +470,19 @@ impl Client {
.expect("Dimension doesn't exist! We should've gotten a login packet by now.")
.add_entity(entity);
}
GamePacket::ClientboundSetEntityDataPacket(_p) => {
ClientboundGamePacket::ClientboundSetEntityDataPacket(_p) => {
// println!("Got set entity data packet {:?}", p);
}
GamePacket::ClientboundUpdateAttributesPacket(_p) => {
ClientboundGamePacket::ClientboundUpdateAttributesPacket(_p) => {
// println!("Got update attributes packet {:?}", p);
}
GamePacket::ClientboundEntityVelocityPacket(_p) => {
ClientboundGamePacket::ClientboundEntityVelocityPacket(_p) => {
// println!("Got entity velocity packet {:?}", p);
}
GamePacket::ClientboundSetEntityLinkPacket(p) => {
ClientboundGamePacket::ClientboundSetEntityLinkPacket(p) => {
println!("Got set entity link packet {:?}", p);
}
GamePacket::ClientboundAddPlayerPacket(p) => {
ClientboundGamePacket::ClientboundAddPlayerPacket(p) => {
println!("Got add player packet {:?}", p);
let entity = Entity::from(p);
client
@ -492,25 +492,25 @@ impl Client {
.expect("Dimension doesn't exist! We should've gotten a login packet by now.")
.add_entity(entity);
}
GamePacket::ClientboundInitializeBorderPacket(p) => {
ClientboundGamePacket::ClientboundInitializeBorderPacket(p) => {
println!("Got initialize border packet {:?}", p);
}
GamePacket::ClientboundSetTimePacket(p) => {
ClientboundGamePacket::ClientboundSetTimePacket(p) => {
println!("Got set time packet {:?}", p);
}
GamePacket::ClientboundSetDefaultSpawnPositionPacket(p) => {
ClientboundGamePacket::ClientboundSetDefaultSpawnPositionPacket(p) => {
println!("Got set default spawn position packet {:?}", p);
}
GamePacket::ClientboundContainerSetContentPacket(p) => {
ClientboundGamePacket::ClientboundContainerSetContentPacket(p) => {
println!("Got container set content packet {:?}", p);
}
GamePacket::ClientboundSetHealthPacket(p) => {
ClientboundGamePacket::ClientboundSetHealthPacket(p) => {
println!("Got set health packet {:?}", p);
}
GamePacket::ClientboundSetExperiencePacket(p) => {
ClientboundGamePacket::ClientboundSetExperiencePacket(p) => {
println!("Got set experience packet {:?}", p);
}
GamePacket::ClientboundTeleportEntityPacket(p) => {
ClientboundGamePacket::ClientboundTeleportEntityPacket(p) => {
let mut dimension_lock = client.dimension.lock()?;
let dimension = dimension_lock.as_mut().unwrap();
@ -523,28 +523,28 @@ impl Client {
},
)?;
}
GamePacket::ClientboundUpdateAdvancementsPacket(p) => {
ClientboundGamePacket::ClientboundUpdateAdvancementsPacket(p) => {
println!("Got update advancements packet {:?}", p);
}
GamePacket::ClientboundRotateHeadPacket(_p) => {
ClientboundGamePacket::ClientboundRotateHeadPacket(_p) => {
// println!("Got rotate head packet {:?}", p);
}
GamePacket::ClientboundMoveEntityPosPacket(p) => {
ClientboundGamePacket::ClientboundMoveEntityPosPacket(p) => {
let mut dimension_lock = client.dimension.lock()?;
let dimension = dimension_lock.as_mut().unwrap();
dimension.move_entity_with_delta(p.entity_id, &p.delta)?;
}
GamePacket::ClientboundMoveEntityPosrotPacket(p) => {
ClientboundGamePacket::ClientboundMoveEntityPosrotPacket(p) => {
let mut dimension_lock = client.dimension.lock()?;
let dimension = dimension_lock.as_mut().unwrap();
dimension.move_entity_with_delta(p.entity_id, &p.delta)?;
}
GamePacket::ClientboundMoveEntityRotPacket(p) => {
ClientboundGamePacket::ClientboundMoveEntityRotPacket(p) => {
println!("Got move entity rot packet {:?}", p);
}
GamePacket::ClientboundKeepAlivePacket(p) => {
ClientboundGamePacket::ClientboundKeepAlivePacket(p) => {
println!("Got keep alive packet {:?}", p);
client
.conn
@ -553,48 +553,48 @@ impl Client {
.write(ServerboundKeepAlivePacket { id: p.id }.get())
.await;
}
GamePacket::ClientboundRemoveEntitiesPacket(p) => {
ClientboundGamePacket::ClientboundRemoveEntitiesPacket(p) => {
println!("Got remove entities packet {:?}", p);
}
GamePacket::ClientboundPlayerChatPacket(p) => {
ClientboundGamePacket::ClientboundPlayerChatPacket(p) => {
println!("Got player chat packet {:?}", p);
tx.send(Event::Chat(ChatPacket::Player(Box::new(p.clone()))))
.unwrap();
}
GamePacket::ClientboundSystemChatPacket(p) => {
ClientboundGamePacket::ClientboundSystemChatPacket(p) => {
println!("Got system chat packet {:?}", p);
tx.send(Event::Chat(ChatPacket::System(p.clone()))).unwrap();
}
GamePacket::ClientboundSoundPacket(p) => {
ClientboundGamePacket::ClientboundSoundPacket(p) => {
println!("Got sound packet {:?}", p);
}
GamePacket::ClientboundLevelEventPacket(p) => {
ClientboundGamePacket::ClientboundLevelEventPacket(p) => {
println!("Got level event packet {:?}", p);
}
GamePacket::ClientboundBlockUpdatePacket(p) => {
ClientboundGamePacket::ClientboundBlockUpdatePacket(p) => {
println!("Got block update packet {:?}", p);
// TODO: update world
}
GamePacket::ClientboundAnimatePacket(p) => {
ClientboundGamePacket::ClientboundAnimatePacket(p) => {
println!("Got animate packet {:?}", p);
}
GamePacket::ClientboundSectionBlocksUpdatePacket(p) => {
ClientboundGamePacket::ClientboundSectionBlocksUpdatePacket(p) => {
println!("Got section blocks update packet {:?}", p);
// TODO: update world
}
GamePacket::ClientboundGameEventPacket(p) => {
ClientboundGamePacket::ClientboundGameEventPacket(p) => {
println!("Got game event packet {:?}", p);
}
GamePacket::ClientboundLevelParticlesPacket(p) => {
ClientboundGamePacket::ClientboundLevelParticlesPacket(p) => {
println!("Got level particles packet {:?}", p);
}
GamePacket::ClientboundServerDataPacket(p) => {
ClientboundGamePacket::ClientboundServerDataPacket(p) => {
println!("Got server data packet {:?}", p);
}
GamePacket::ClientboundSetEquipmentPacket(p) => {
ClientboundGamePacket::ClientboundSetEquipmentPacket(p) => {
println!("Got set equipment packet {:?}", p);
}
GamePacket::ClientboundUpdateMobEffectPacket(p) => {
ClientboundGamePacket::ClientboundUpdateMobEffectPacket(p) => {
println!("Got update mob effect packet {:?}", p);
}
_ => panic!("Unexpected packet {:?}", packet),

View file

@ -1,11 +1,12 @@
///! Ping Minecraft servers.
use azalea_protocol::{
connect::HandshakeConnection,
connect::Connection,
packets::{
handshake::client_intention_packet::ClientIntentionPacket,
status::{
clientbound_status_response_packet::ClientboundStatusResponsePacket,
serverbound_status_request_packet::ServerboundStatusRequestPacket, StatusPacket,
serverbound_status_request_packet::ServerboundStatusRequestPacket,
ClientboundStatusPacket,
},
ConnectionProtocol, PROTOCOL_VERSION,
},
@ -17,7 +18,7 @@ pub async fn ping_server(
) -> Result<ClientboundStatusResponsePacket, String> {
let resolved_address = resolver::resolve_address(address).await?;
let mut conn = HandshakeConnection::new(&resolved_address).await?;
let mut conn = Connection::new(&resolved_address).await?;
// send the client intention packet and switch to the status state
conn.write(
@ -38,7 +39,6 @@ pub async fn ping_server(
let packet = conn.read().await.unwrap();
match packet {
StatusPacket::ClientboundStatusResponsePacket(p) => Ok(p),
_ => Err("Invalid packet type".to_string()),
ClientboundStatusPacket::ClientboundStatusResponsePacket(p) => Ok(p),
}
}

View file

@ -40,24 +40,56 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke
contents.into()
}
#[proc_macro_derive(GamePacket, attributes(var))]
pub fn derive_game_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::game::GamePacket})
#[proc_macro_derive(ServerboundGamePacket, attributes(var))]
pub fn derive_serverbound_game_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::game::ServerboundGamePacket})
}
#[proc_macro_derive(ServerboundHandshakePacket, attributes(var))]
pub fn derive_serverbound_handshake_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::handshake::ServerboundHandshakePacket},
)
}
#[proc_macro_derive(ServerboundLoginPacket, attributes(var))]
pub fn derive_serverbound_login_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::login::ServerboundLoginPacket},
)
}
#[proc_macro_derive(ServerboundStatusPacket, attributes(var))]
pub fn derive_serverbound_status_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::status::ServerboundStatusPacket},
)
}
#[proc_macro_derive(HandshakePacket, attributes(var))]
pub fn derive_handshake_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::handshake::HandshakePacket})
#[proc_macro_derive(ClientboundGamePacket, attributes(var))]
pub fn derive_clientbound_game_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::game::ClientboundGamePacket})
}
#[proc_macro_derive(LoginPacket, attributes(var))]
pub fn derive_login_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::login::LoginPacket})
#[proc_macro_derive(ClientboundHandshakePacket, attributes(var))]
pub fn derive_clientbound_handshake_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::handshake::ClientboundHandshakePacket},
)
}
#[proc_macro_derive(StatusPacket, attributes(var))]
pub fn derive_status_packet(input: TokenStream) -> TokenStream {
as_packet_derive(input, quote! {crate::packets::status::StatusPacket})
#[proc_macro_derive(ClientboundLoginPacket, attributes(var))]
pub fn derive_clientbound_login_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::login::ClientboundLoginPacket},
)
}
#[proc_macro_derive(ClientboundStatusPacket, attributes(var))]
pub fn derive_clientbound_status_packet(input: TokenStream) -> TokenStream {
as_packet_derive(
input,
quote! {crate::packets::status::ClientboundStatusPacket},
)
}
#[derive(Debug)]
@ -154,23 +186,34 @@ impl Parse for DeclareStatePackets {
pub fn declare_state_packets(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeclareStatePackets);
let state_name = input.name;
let state_name_litstr = syn::LitStr::new(&state_name.to_string(), state_name.span());
let serverbound_state_name =
Ident::new(&format!("Serverbound{}", input.name), input.name.span());
let clientbound_state_name =
Ident::new(&format!("Clientbound{}", input.name), input.name.span());
let mut enum_contents = quote!();
let mut id_match_contents = quote!();
let mut write_match_contents = quote!();
let state_name_litstr = syn::LitStr::new(&input.name.to_string(), input.name.span());
let has_serverbound_packets = !input.serverbound.packets.is_empty();
let has_clientbound_packets = !input.clientbound.packets.is_empty();
let mut serverbound_enum_contents = quote!();
let mut clientbound_enum_contents = quote!();
let mut serverbound_id_match_contents = quote!();
let mut clientbound_id_match_contents = quote!();
let mut serverbound_write_match_contents = quote!();
let mut clientbound_write_match_contents = quote!();
let mut serverbound_read_match_contents = quote!();
let mut clientbound_read_match_contents = quote!();
for PacketIdPair { id, module, name } in input.serverbound.packets {
enum_contents.extend(quote! {
serverbound_enum_contents.extend(quote! {
#name(#module::#name),
});
id_match_contents.extend(quote! {
#state_name::#name(_packet) => #id,
serverbound_id_match_contents.extend(quote! {
#serverbound_state_name::#name(_packet) => #id,
});
write_match_contents.extend(quote! {
#state_name::#name(packet) => packet.write(buf),
serverbound_write_match_contents.extend(quote! {
#serverbound_state_name::#name(packet) => packet.write(buf),
});
serverbound_read_match_contents.extend(quote! {
#id => #module::#name::read(buf)?,
@ -178,63 +221,115 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
}
for PacketIdPair { id, module, name } in input.clientbound.packets {
// let name_litstr = syn::LitStr::new(&name.to_string(), name.span());
enum_contents.extend(quote! {
clientbound_enum_contents.extend(quote! {
#name(#module::#name),
});
id_match_contents.extend(quote! {
#state_name::#name(_packet) => #id,
clientbound_id_match_contents.extend(quote! {
#clientbound_state_name::#name(_packet) => #id,
});
write_match_contents.extend(quote! {
#state_name::#name(packet) => packet.write(buf),
clientbound_write_match_contents.extend(quote! {
#clientbound_state_name::#name(packet) => packet.write(buf),
});
clientbound_read_match_contents.extend(quote! {
#id => #module::#name::read(buf)?,
});
}
quote! {
if !has_serverbound_packets {
serverbound_id_match_contents.extend(quote! {
_ => panic!("This enum is empty and can't exist.")
});
serverbound_write_match_contents.extend(quote! {
_ => panic!("This enum is empty and can't exist.")
});
}
if !has_clientbound_packets {
clientbound_id_match_contents.extend(quote! {
_ => panic!("This enum is empty and can't exist.")
});
clientbound_write_match_contents.extend(quote! {
_ => panic!("This enum is empty and can't exist.")
});
}
let mut contents = quote! {
#[derive(Clone, Debug)]
pub enum #state_name
pub enum #serverbound_state_name
where
Self: Sized,
{
#serverbound_enum_contents
}
#[derive(Clone, Debug)]
pub enum #clientbound_state_name
where
Self: Sized,
{
#enum_contents
#clientbound_enum_contents
}
};
impl crate::packets::ProtocolPacket for #state_name {
contents.extend(quote! {
#[allow(unreachable_code)]
impl crate::packets::ProtocolPacket for #serverbound_state_name {
fn id(&self) -> u32 {
match self {
#id_match_contents
#serverbound_id_match_contents
}
}
fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
match self {
#write_match_contents
#serverbound_write_match_contents
}
}
/// Read a packet by its id, ConnectionProtocol, and flow
fn read(
id: u32,
flow: &crate::connect::PacketFlow,
buf: &mut impl std::io::Read,
) -> Result<#state_name, String>
) -> Result<#serverbound_state_name, String>
where
Self: Sized,
{
Ok(match flow {
crate::connect::PacketFlow::ServerToClient => match id {
#clientbound_read_match_contents
_ => return Err(format!("Unknown ServerToClient {} packet id: {}", #state_name_litstr, id)),
},
crate::connect::PacketFlow::ClientToServer => match id {
#serverbound_read_match_contents
_ => return Err(format!("Unknown ClientToServer {} packet id: {}", #state_name_litstr, id)),
},
Ok(match id {
#serverbound_read_match_contents
_ => return Err(format!("Unknown Serverbound {} packet id: {}", #state_name_litstr, id)),
})
}
}
}
.into()
});
contents.extend(quote! {
#[allow(unreachable_code)]
impl crate::packets::ProtocolPacket for #clientbound_state_name {
fn id(&self) -> u32 {
match self {
#clientbound_id_match_contents
}
}
fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
match self {
#clientbound_write_match_contents
}
}
/// Read a packet by its id, ConnectionProtocol, and flow
fn read(
id: u32,
buf: &mut impl std::io::Read,
) -> Result<#clientbound_state_name, String>
where
Self: Sized,
{
Ok(match id {
#clientbound_read_match_contents
_ => return Err(format!("Unknown Clientbound {} packet id: {}", #state_name_litstr, id)),
})
}
}
});
contents.into()
}

View file

@ -1,53 +1,56 @@
//! parse sending and receiving packets with a server.
use crate::packets::game::GamePacket;
use crate::packets::handshake::HandshakePacket;
use crate::packets::login::LoginPacket;
use crate::packets::status::StatusPacket;
use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket};
use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket};
use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket};
use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket};
use crate::packets::ProtocolPacket;
use crate::read::read_packet;
use crate::write::write_packet;
use crate::ServerIpAddress;
use azalea_crypto::{Aes128CfbDec, Aes128CfbEnc};
use std::fmt::Debug;
use std::marker::PhantomData;
use tokio::net::TcpStream;
#[derive(Debug, Clone, Copy)]
pub enum PacketFlow {
ClientToServer,
ServerToClient,
}
pub struct HandshakeConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
}
pub struct GameConnection {
pub flow: PacketFlow,
pub struct Connection<R: ProtocolPacket, W: ProtocolPacket> {
/// The buffered writer
pub stream: TcpStream,
pub compression_threshold: Option<u32>,
pub enc_cipher: Option<Aes128CfbEnc>,
pub dec_cipher: Option<Aes128CfbDec>,
_reading: PhantomData<R>,
_writing: PhantomData<W>,
}
pub struct StatusConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
impl<R, W> Connection<R, W>
where
R: ProtocolPacket + Debug,
W: ProtocolPacket + Debug,
{
pub async fn read(&mut self) -> Result<R, String> {
read_packet::<R, _>(
&mut self.stream,
self.compression_threshold,
&mut self.dec_cipher,
)
.await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: W) {
write_packet(
packet,
&mut self.stream,
self.compression_threshold,
&mut self.enc_cipher,
)
.await;
}
}
pub struct LoginConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
pub compression_threshold: Option<u32>,
pub enc_cipher: Option<Aes128CfbEnc>,
pub dec_cipher: Option<Aes128CfbDec>,
}
impl HandshakeConnection {
pub async fn new(address: &ServerIpAddress) -> Result<HandshakeConnection, String> {
impl Connection<ClientboundHandshakePacket, ServerboundHandshakePacket> {
pub async fn new(address: &ServerIpAddress) -> Result<Self, String> {
let ip = address.ip;
let port = address.port;
@ -60,95 +63,26 @@ impl HandshakeConnection {
.set_nodelay(true)
.expect("Error enabling tcp_nodelay");
Ok(HandshakeConnection {
flow: PacketFlow::ServerToClient,
Ok(Connection {
stream,
})
}
pub fn login(self) -> LoginConnection {
LoginConnection {
flow: self.flow,
stream: self.stream,
compression_threshold: None,
enc_cipher: None,
dec_cipher: None,
}
_reading: PhantomData,
_writing: PhantomData,
})
}
pub fn status(self) -> StatusConnection {
StatusConnection {
flow: self.flow,
stream: self.stream,
}
pub fn login(self) -> Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
Connection::from(self)
}
pub async fn read(&mut self) -> Result<HandshakePacket, String> {
read_packet::<HandshakePacket, _>(&self.flow, &mut self.stream, None, &mut None).await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: HandshakePacket) {
write_packet(packet, &mut self.stream, None, &mut None).await;
pub fn status(self) -> Connection<ClientboundStatusPacket, ServerboundStatusPacket> {
Connection::from(self)
}
}
impl GameConnection {
pub async fn read(&mut self) -> Result<GamePacket, String> {
read_packet::<GamePacket, _>(
&self.flow,
&mut self.stream,
self.compression_threshold,
&mut self.dec_cipher,
)
.await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: GamePacket) {
write_packet(
packet,
&mut self.stream,
self.compression_threshold,
&mut self.enc_cipher,
)
.await;
}
}
impl StatusConnection {
pub async fn read(&mut self) -> Result<StatusPacket, String> {
read_packet::<StatusPacket, _>(&self.flow, &mut self.stream, None, &mut None).await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: StatusPacket) {
write_packet(packet, &mut self.stream, None, &mut None).await;
}
}
impl LoginConnection {
pub async fn read(&mut self) -> Result<LoginPacket, String> {
read_packet::<LoginPacket, _>(
&self.flow,
&mut self.stream,
self.compression_threshold,
&mut self.dec_cipher,
)
.await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: LoginPacket) {
write_packet(
packet,
&mut self.stream,
self.compression_threshold,
&mut self.enc_cipher,
)
.await;
}
impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
pub fn set_compression_threshold(&mut self, threshold: i32) {
// if you pass a threshold of 0 or less, compression is disabled
if threshold > 0 {
@ -165,13 +99,30 @@ impl LoginConnection {
self.dec_cipher = Some(dec_cipher);
}
pub fn game(self) -> GameConnection {
GameConnection {
flow: self.flow,
stream: self.stream,
compression_threshold: self.compression_threshold,
enc_cipher: self.enc_cipher,
dec_cipher: self.dec_cipher,
pub fn game(self) -> Connection<ClientboundGamePacket, ServerboundGamePacket> {
Connection::from(self)
}
}
// rust doesn't let us implement From because allegedly it conflicts with
// `core`'s "impl<T> From<T> for T" so we do this instead
impl<R1, W1> Connection<R1, W1>
where
R1: ProtocolPacket + Debug,
W1: ProtocolPacket + Debug,
{
fn from<R2, W2>(connection: Connection<R1, W1>) -> Connection<R2, W2>
where
R2: ProtocolPacket + Debug,
W2: ProtocolPacket + Debug,
{
Connection {
stream: connection.stream,
compression_threshold: connection.compression_threshold,
enc_cipher: connection.enc_cipher,
dec_cipher: connection.dec_cipher,
_reading: PhantomData,
_writing: PhantomData,
}
}
}

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf;
use azalea_core::EntityPos;
use azalea_entity::Entity;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundAddEntityPacket {
/// The id of the entity.
#[var]

View file

@ -1,11 +1,11 @@
use azalea_buf::McBuf;
use azalea_core::EntityPos;
use azalea_entity::Entity;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use uuid::Uuid;
/// This packet is sent by the server when a player comes into visible range, not when a player joins.
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundAddPlayerPacket {
#[var]
pub id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundAnimatePacket {
#[var]
pub id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundBlockChangedAckPacket {
#[var]
pub sequence: i32,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::BlockPos;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundBlockUpdatePacket {
pub pos: BlockPos,
// TODO: in vanilla this is a BlockState, but here we just have it as a number.

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::Difficulty;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundChangeDifficultyPacket {
pub difficulty: Difficulty,
pub locked: bool,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::component::Component;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundChatPreviewPacket {
pub query_id: i32,
pub preview: Option<Component>,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundContainerSetContentPacket {
pub container_id: u8,
#[var]

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundCustomChatCompletionsPacket {
pub action: Action,
pub entries: Vec<String>,

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_buf::UnsizedByteArray;
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundCustomPayloadPacket {
pub identifier: ResourceLocation,
pub data: UnsizedByteArray,

View file

@ -2,13 +2,13 @@ use azalea_buf::McBuf;
use azalea_buf::McBufVarReadable;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::{
hash::Hash,
io::{Read, Write},
};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundDeclareCommandsPacket {
pub entries: Vec<BrigadierNodeStub>,
#[var]

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_crypto::MessageSignature;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundDeleteChatPacket {
pub message_signature: MessageSignature,
}

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::component::Component;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundDisconnectPacket {
pub reason: Component,
}

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
// we can't identify the status in azalea-protocol since they vary depending on the entity
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundEntityEventPacket {
pub entity_id: u32,
pub event_id: u8,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundEntityVelocityPacket {
#[var]
pub entity_id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundGameEventPacket {
pub event: EventType,
pub param: f32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundInitializeBorderPacket {
pub new_center_x: f64,
pub new_center_z: f64,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundKeepAlivePacket {
pub id: u64,
}

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use super::clientbound_light_update_packet::ClientboundLightUpdatePacketData;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundLevelChunkWithLightPacket {
pub x: i32,
pub z: i32,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::BlockPos;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundLevelEventPacket {
pub type_: i32,
pub pos: BlockPos,

View file

@ -1,9 +1,9 @@
use azalea_buf::{McBufReadable, McBufVarReadable, McBufWritable};
use azalea_core::ParticleData;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, GamePacket)]
#[derive(Clone, Debug, ClientboundGamePacket)]
pub struct ClientboundLevelParticlesPacket {
#[var]
pub particle_id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::{BitSet, McBuf};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundLightUpdatePacket {
pub x: i32,
pub z: i32,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::{GameType, GlobalPos, OptionalGameType, ResourceLocation};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundLoginPacket {
pub player_id: u32,
pub hardcore: bool,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::PositionDelta8;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundMoveEntityPosPacket {
#[var]
pub entity_id: u32,

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::PositionDelta8;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
/// This packet is sent by the server when an entity moves less then 8 blocks.
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundMoveEntityPosrotPacket {
#[var]
pub entity_id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundMoveEntityRotPacket {
#[var]
pub entity_id: i32,

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundPlayerAbilitiesPacket {
pub flags: PlayerAbilitiesFlags,
pub flying_speed: f32,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_crypto::{MessageSignature, SignedMessageHeader};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundPlayerChatHeaderPacket {
pub header: SignedMessageHeader,
pub header_signature: MessageSignature,

View file

@ -2,11 +2,11 @@ use azalea_buf::{BitSet, McBuf, McBufReadable, McBufVarWritable};
use azalea_buf::{McBufVarReadable, McBufWritable};
use azalea_chat::component::Component;
use azalea_crypto::{MessageSignature, SignedMessageHeader};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundPlayerChatPacket {
pub message: PlayerChatMessage,
pub chat_type: ChatTypeBound,

View file

@ -1,11 +1,11 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
use azalea_chat::component::Component;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundPlayerInfoPacket {
pub action: Action,
}

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundPlayerPositionPacket {
pub x: f64,
pub y: f64,

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundRecipePacket {
pub action: State,
pub settings: RecipeBookSettings,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundRemoveEntitiesPacket {
#[var]
pub entity_ids: Vec<u32>,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundRotateHeadPacket {
#[var]
pub entity_id: u32,

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
use azalea_core::{ChunkSectionBlockPos, ChunkSectionPos};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSectionBlocksUpdatePacket {
pub section_pos: ChunkSectionPos,
pub suppress_light_updates: bool,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::component::Component;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundServerDataPacket {
pub motd: Option<Component>,
pub icon_base64: Option<String>,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
/// Sent to change the player's slot selection.
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetCarriedItemPacket {
pub slot: u8,
}

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetChunkCacheCenterPacket {
#[var]
pub x: i32,

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::BlockPos;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetDefaultSpawnPositionPacket {
pub pos: BlockPos,
pub angle: f32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetDisplayChatPreviewPacket {
pub enabled: bool,
}

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_entity::EntityMetadata;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetEntityDataPacket {
#[var]
pub id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetEntityLinkPacket {
pub source_id: u32,
pub dest_id: u32,

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use azalea_buf::{McBufReadable, McBufWritable};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetEquipmentPacket {
#[var]
pub entity: i32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetExperiencePacket {
pub experience_progress: f32,
#[var]

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetHealthPacket {
pub health: f32,
#[var]

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetTimePacket {
pub game_time: u64,
pub day_time: u64,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundPacket {
#[var]
// TODO: use the sound registry instead of just being a u32

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::component::Component;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSystemChatPacket {
pub content: Component,
pub overlay: bool,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundTeleportEntityPacket {
#[var]
pub id: u32,

View file

@ -1,13 +1,13 @@
use azalea_buf::{McBuf, McBufReadable, McBufWritable};
use azalea_chat::component::Component;
use azalea_core::{ResourceLocation, Slot};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::{
collections::HashMap,
io::{Read, Write},
};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateAdvancementsPacket {
pub reset: bool,
pub added: HashMap<ResourceLocation, Advancement>,

View file

@ -1,11 +1,11 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::io::{Read, Write};
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateAttributesPacket {
#[var]
pub entity_id: u32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateMobEffectPacket {
#[var]
pub entity_id: u32,

View file

@ -2,11 +2,11 @@ use std::io::{Read, Write};
use azalea_buf::McBuf;
use azalea_core::{ResourceLocation, Slot};
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateRecipesPacket {
pub recipes: Vec<Recipe>,
}

View file

@ -1,14 +1,14 @@
use azalea_buf::McBuf;
use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
use std::ops::Deref;
use std::{
collections::HashMap,
io::{Read, Write},
};
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateTagsPacket {
pub tags: TagMap,
}

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateViewDistancePacket {
#[var]
pub view_distance: i32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundAcceptTeleportationPacket {
#[var]
pub id: u32,

View file

@ -1,8 +1,8 @@
use crate::packets::game::clientbound_player_chat_packet::LastSeenMessagesUpdate;
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundChatAckPacket {
pub last_seen_messages: LastSeenMessagesUpdate,
}

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf;
use azalea_crypto::MessageSignature;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
use super::clientbound_player_chat_packet::LastSeenMessagesUpdate;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundChatCommandPacket {
pub command: String,
// TODO: Choose a real timestamp type

View file

@ -1,9 +1,9 @@
use crate::packets::game::clientbound_player_chat_packet::LastSeenMessagesUpdate;
use azalea_buf::McBuf;
use azalea_crypto::MessageSignature;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundChatPacket {
pub message: String,
pub timestamp: u64,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundChatPreviewPacket {
pub query_id: i32,
pub query: String,

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_buf::UnsizedByteArray;
use azalea_core::ResourceLocation;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundCustomPayloadPacket {
pub identifier: ResourceLocation,
pub data: UnsizedByteArray,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundKeepAlivePacket {
pub id: u64,
}

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundMovePlayerPacketPos {
pub x: f64,
pub y: f64,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundMovePlayerPacketPosRot {
pub x: f64,
pub y: f64,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundMovePlayerPacketRot {
pub y_rot: f32,
pub x_rot: f32,

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::GamePacket;
use packet_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, GamePacket)]
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundMovePlayerPacketStatusOnly {
pub on_ground: bool,
}

View file

@ -1,9 +1,9 @@
use crate::packets::ConnectionProtocol;
use azalea_buf::McBuf;
use packet_macros::HandshakePacket;
use packet_macros::ServerboundHandshakePacket;
use std::hash::Hash;
#[derive(Hash, Clone, Debug, McBuf, HandshakePacket)]
#[derive(Hash, Clone, Debug, McBuf, ServerboundHandshakePacket)]
pub struct ClientIntentionPacket {
#[var]
pub protocol_version: u32,

View file

@ -4,8 +4,8 @@ use packet_macros::declare_state_packets;
declare_state_packets!(
HandshakePacket,
Serverbound => {},
Clientbound => {
Serverbound => {
0x00: client_intention_packet::ClientIntentionPacket,
}
},
Clientbound => {}
);

View file

@ -1,9 +1,9 @@
use azalea_buf::{McBuf, UnsizedByteArray};
use azalea_core::ResourceLocation;
use packet_macros::LoginPacket;
use packet_macros::ClientboundLoginPacket;
use std::hash::Hash;
#[derive(Hash, Clone, Debug, McBuf, LoginPacket)]
#[derive(Hash, Clone, Debug, McBuf, ClientboundLoginPacket)]
pub struct ClientboundCustomQueryPacket {
#[var]
pub transaction_id: u32,

View file

@ -1,6 +1,6 @@
use std::io::{Read, Write};
use super::LoginPacket;
use super::ClientboundLoginPacket;
use azalea_auth::game_profile::GameProfile;
use azalea_buf::{McBufReadable, Readable, SerializableUuid, Writable};
use uuid::Uuid;
@ -12,8 +12,8 @@ pub struct ClientboundGameProfilePacket {
// TODO: add derives to GameProfile and have an impl McBufReadable/Writable for GameProfile
impl ClientboundGameProfilePacket {
pub fn get(self) -> LoginPacket {
LoginPacket::ClientboundGameProfilePacket(self)
pub fn get(self) -> ClientboundLoginPacket {
ClientboundLoginPacket::ClientboundGameProfilePacket(self)
}
pub fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
@ -24,7 +24,7 @@ impl ClientboundGameProfilePacket {
Ok(())
}
pub fn read(buf: &mut impl Read) -> Result<LoginPacket, String> {
pub fn read(buf: &mut impl Read) -> Result<ClientboundLoginPacket, String> {
let uuid = Uuid::read_from(buf)?;
let name = buf.read_utf_with_len(16)?;
Ok(ClientboundGameProfilePacket {

View file

@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use packet_macros::LoginPacket;
use packet_macros::ClientboundLoginPacket;
#[derive(Clone, Debug, McBuf, LoginPacket)]
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
pub struct ClientboundHelloPacket {
// TODO: make this len thing work
// #[len(20)]

View file

@ -5,7 +5,7 @@ use std::{
use azalea_buf::{Readable, Writable};
use super::LoginPacket;
use super::ClientboundLoginPacket;
#[derive(Hash, Clone, Debug)]
pub struct ClientboundLoginCompressionPacket {
@ -13,8 +13,8 @@ pub struct ClientboundLoginCompressionPacket {
}
impl ClientboundLoginCompressionPacket {
pub fn get(self) -> LoginPacket {
LoginPacket::ClientboundLoginCompressionPacket(self)
pub fn get(self) -> ClientboundLoginPacket {
ClientboundLoginPacket::ClientboundLoginCompressionPacket(self)
}
pub fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
@ -22,7 +22,7 @@ impl ClientboundLoginCompressionPacket {
Ok(())
}
pub fn read(buf: &mut impl Read) -> Result<LoginPacket, String> {
pub fn read(buf: &mut impl Read) -> Result<ClientboundLoginPacket, String> {
let compression_threshold = buf.read_varint()?;
Ok(ClientboundLoginCompressionPacket {

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::component::Component;
use packet_macros::LoginPacket;
use packet_macros::ClientboundLoginPacket;
#[derive(Clone, Debug, McBuf, LoginPacket)]
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
pub struct ClientboundLoginDisconnectPacket {
pub reason: Component,
}

View file

@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use packet_macros::LoginPacket;
use packet_macros::ServerboundLoginPacket;
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, LoginPacket)]
#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)]
pub struct ServerboundHelloPacket {
pub username: String,
pub public_key: Option<ProfilePublicKeyData>,

View file

@ -1,11 +1,11 @@
use azalea_buf::McBuf;
use azalea_crypto::SaltSignaturePair;
use packet_macros::LoginPacket;
use packet_macros::ServerboundLoginPacket;
use std::io::{Read, Write};
use azalea_buf::{McBufReadable, McBufWritable};
#[derive(Clone, Debug, McBuf, LoginPacket)]
#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)]
pub struct ServerboundKeyPacket {
pub key_bytes: Vec<u8>,
pub nonce_or_salt_signature: NonceOrSaltSignature,

View file

@ -3,7 +3,6 @@ pub mod handshake;
pub mod login;
pub mod status;
use crate::connect::PacketFlow;
use azalea_buf::{McBufWritable, Readable, Writable};
use std::io::{Read, Write};
@ -29,14 +28,6 @@ impl ConnectionProtocol {
}
}
#[derive(Clone, Debug)]
pub enum Packet {
Game(Box<game::GamePacket>),
Handshake(Box<handshake::HandshakePacket>),
Login(Box<login::LoginPacket>),
Status(Box<status::StatusPacket>),
}
/// An enum of packets for a certain protocol
pub trait ProtocolPacket
where
@ -45,7 +36,7 @@ where
fn id(&self) -> u32;
/// Read a packet by its id, ConnectionProtocol, and flow
fn read(id: u32, flow: &PacketFlow, buf: &mut impl Read) -> Result<Self, String>;
fn read(id: u32, buf: &mut impl Read) -> Result<Self, String>;
fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
}

View file

@ -1,12 +1,9 @@
use std::io::{Read, Write};
use super::ClientboundStatusPacket;
use azalea_buf::Readable;
use azalea_chat::component::Component;
use serde::Deserialize;
use serde_json::Value;
use azalea_buf::Readable;
use super::StatusPacket;
use std::io::{Read, Write};
#[derive(Clone, Debug, Deserialize)]
pub struct Version {
@ -37,15 +34,15 @@ pub struct ClientboundStatusResponsePacket {
}
impl ClientboundStatusResponsePacket {
pub fn get(self) -> StatusPacket {
StatusPacket::ClientboundStatusResponsePacket(self)
pub fn get(self) -> ClientboundStatusPacket {
ClientboundStatusPacket::ClientboundStatusResponsePacket(self)
}
pub fn write(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> {
Ok(())
}
pub fn read(buf: &mut impl Read) -> Result<StatusPacket, String> {
pub fn read(buf: &mut impl Read) -> Result<ClientboundStatusPacket, String> {
let status_string = buf.read_utf()?;
let status_json: Value =
serde_json::from_str(status_string.as_str()).expect("Server status isn't valid JSON");

View file

@ -1,5 +1,5 @@
use azalea_buf::McBuf;
use packet_macros::StatusPacket;
use packet_macros::ServerboundStatusPacket;
#[derive(Clone, Debug, McBuf, StatusPacket)]
#[derive(Clone, Debug, McBuf, ServerboundStatusPacket)]
pub struct ServerboundStatusRequestPacket {}

View file

@ -1,4 +1,4 @@
use crate::{connect::PacketFlow, packets::ProtocolPacket};
use crate::packets::ProtocolPacket;
use azalea_buf::{read_varint_async, Readable};
use azalea_crypto::Aes128CfbDec;
use flate2::read::ZlibDecoder;
@ -31,13 +31,10 @@ where
}
}
fn packet_decoder<P: ProtocolPacket>(
stream: &mut impl Read,
flow: &PacketFlow,
) -> Result<P, String> {
fn packet_decoder<P: ProtocolPacket>(stream: &mut impl Read) -> Result<P, String> {
// Packet ID
let packet_id = stream.read_varint()?;
P::read(packet_id.try_into().unwrap(), flow, stream)
P::read(packet_id.try_into().unwrap(), stream)
}
// this is always true in multiplayer, false in singleplayer
@ -121,7 +118,6 @@ where
}
pub async fn read_packet<'a, P: ProtocolPacket, R>(
flow: &PacketFlow,
stream: &'a mut R,
compression_threshold: Option<u32>,
cipher: &mut Option<Aes128CfbDec>,
@ -150,7 +146,7 @@ where
}
// println!("decoding packet ({}ms)", start_time.elapsed().as_millis());
let packet = packet_decoder(&mut buf.as_slice(), flow)?;
let packet = packet_decoder(&mut buf.as_slice())?;
// println!("decoded packet ({}ms)", start_time.elapsed().as_millis());
Ok(packet)