use std::io::{Write, Result}; use super::PacketWriter; use world::Chunk; use world::{SIZE_X, SIZE_Y, SIZE_Z}; use world::Position; use utils::math; #[derive(Debug, Clone)] pub enum ClientboundPacket { ChatMessage { message: String }, EntityMetadataCrouch { entity_id: i32, is_crouching: bool }, Disconnect { reason: String }, } pub fn write_handshake(writer: &mut PacketWriter) -> Result<()> { writer.write_u8(0x02)?; writer.write_string("-")?; // ignore auth ig Ok(()) } pub fn write_login(writer: &mut PacketWriter, entity_id: i32, world_seed: i64, dimension: i8) -> Result<()> { writer.write_u8(0x01)?; writer.write_i32(entity_id)?; writer.write_string("")?; // unused, yet i did not look into why; maybe i should, maybbe not writer.write_i64(world_seed)?; writer.write_u8(dimension as u8)?; Ok(()) } pub fn write_player_pos(writer: &mut PacketWriter, position: Position, stance: f64) -> Result<()> { writer.write_u8(0x0D)?; writer.write_f64(position.x)?; writer.write_f64(stance)?; writer.write_f64(position.y)?; writer.write_f64(position.z)?; writer.write_f32(position.yaw)?; writer.write_f32(position.pitch)?; writer.write_bool(position.on_ground)?; Ok(()) } pub fn write_player_pos_nostance(writer: &mut PacketWriter, position: Position) -> Result<()> { write_player_pos(writer, position, position.y + 1.62) } pub fn set_spawn_pos(writer: &mut PacketWriter, x: i32, y: i32, z: i32) -> Result<()> { writer.write_u8(0x06)?; writer.write_i32(x)?; writer.write_i32(y)?; writer.write_i32(z)?; Ok(()) } pub fn send_prechunk(writer: &mut PacketWriter, chunk_x: i32, chunk_z: i32, mode: bool) -> Result<()> { writer.write_u8(0x32)?; writer.write_i32(chunk_x)?; writer.write_i32(chunk_z)?; writer.write_bool(mode)?; Ok(()) } pub fn send_chunk(writer: &mut PacketWriter, chunk: &Chunk) -> Result<()> { let data = chunk.compressed()?; writer.write_u8(0x33)?; writer.write_i32(chunk.x * 16)?; writer.write_i16(0)?; writer.write_i32(chunk.z * 16)?; writer.write_u8((SIZE_X - 1) as u8)?; writer.write_u8((SIZE_Y - 1) as u8)?; writer.write_u8((SIZE_Z - 1) as u8)?; writer.write_i32(data.len() as i32)?; writer.write_bytes(&data)?; Ok(()) } pub fn write_keepalive(writer: &mut PacketWriter) -> Result<()> { writer.write_u8(0x00)?; Ok(()) } /// spawn player pub fn write_spawnplayer(writer: &mut PacketWriter, entity_id: i32, username: &str, position: Position, current_item: i16) -> Result<()> { writer.write_u8(0x14)?; writer.write_i32(entity_id)?; writer.write_string(username)?; writer.write_i32((position.x * 32.0) as i32)?; writer.write_i32((position.y * 32.0) as i32)?; writer.write_i32((position.z * 32.0) as i32)?; writer.write_u8(math::angle_byte(position.yaw))?; writer.write_u8(math::angle_byte(position.pitch))?; writer.write_i16(current_item)?; Ok(()) } /// destroy entity pub fn destroy_entity(writer: &mut PacketWriter, entity_id: i32) -> Result<()> { writer.write_u8(0x1D)?; writer.write_i32(entity_id)?; Ok(()) } /// entity teleport pub fn entity_teleport(writer: &mut PacketWriter, entity_id: i32, position: Position) -> Result<()> { writer.write_u8(0x22)?; writer.write_i32(entity_id)?; writer.write_i32((position.x * 32.0) as i32)?; writer.write_i32((position.y * 32.0) as i32)?; writer.write_i32((position.z * 32.0) as i32)?; writer.write_u8(math::angle_byte(position.yaw))?; writer.write_u8(math::angle_byte(position.pitch))?; Ok(()) } pub fn write_chatmsg(writer: &mut PacketWriter, message: &str) -> Result<()> { writer.write_u8(0x03)?; writer.write_string(message)?; Ok(()) } pub fn write_kick(writer: &mut PacketWriter, reason: &str) -> Result<()> { writer.write_u8(0xFF)?; writer.write_string(reason)?; Ok(()) } pub fn write_player_crouch_lol(writer: &mut PacketWriter, entity_id: i32, sneaking: bool) -> Result<()> { writer.write_u8(0x28)?; writer.write_i32(entity_id)?; writer.write_u8(0x00)?; writer.write_u8(if sneaking { 0x02 } else { 0x00 })?; writer.write_u8(0x7F)?; Ok(()) }