From 4d75415130a008f83c3bd594ca4cefd01f3d53dd Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 1 May 2022 18:59:07 -0500 Subject: [PATCH 01/29] start adding azalea-world --- Cargo.lock | 4 ++ Cargo.toml | 1 + azalea-client/src/connect.rs | 1 + ...ientbound_level_chunk_with_light_packet.rs | 4 +- azalea-world/Cargo.toml | 8 ++++ azalea-world/README.md | 3 ++ azalea-world/src/lib.rs | 43 +++++++++++++++++++ 7 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 azalea-world/Cargo.toml create mode 100644 azalea-world/README.md create mode 100644 azalea-world/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 254dc5db..2e028643 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,6 +164,10 @@ dependencies = [ "uuid", ] +[[package]] +name = "azalea-world" +version = "0.1.0" + [[package]] name = "bitflags" version = "1.3.2" diff --git a/Cargo.toml b/Cargo.toml index f7272ff7..a7b0adb5 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "azalea-nbt", "azalea-brigadier", "azalea-crypto", + "azalea-world", ] [profile.release] diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 826bce3d..52ae1071 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -233,6 +233,7 @@ impl Client { } GamePacket::ClientboundLevelChunkWithLightPacket(p) => { println!("Got chunk with light packet {} {}", p.x, p.z); + // p.chunk_data } GamePacket::ClientboundLightUpdatePacket(p) => { println!("Got light update packet {:?}", p); diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index 1d017c2a..abd936dc 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -30,5 +30,7 @@ pub struct BlockEntity { pub struct ChunkSection {} impl ClientboundLevelChunkPacketData { - pub fn read(world_height: u32) {} + pub fn read(world_height: u32) { + // let section_count + } } diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml new file mode 100644 index 00000000..afae93a7 --- /dev/null +++ b/azalea-world/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "azalea-world" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/azalea-world/README.md b/azalea-world/README.md new file mode 100644 index 00000000..6f68ab42 --- /dev/null +++ b/azalea-world/README.md @@ -0,0 +1,3 @@ +# Azalea World + +The Minecraft world representation used in Azalea. diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs new file mode 100644 index 00000000..20043bbf --- /dev/null +++ b/azalea-world/src/lib.rs @@ -0,0 +1,43 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert_eq!(result, 4); + } +} + +pub struct Chunk { + sections: Vec
, +} + +pub struct Section { + states: PalettedContainer, + biomes: PalettedContainer, +} + +pub struct PalettedContainer { + bits_per_entry: u8, + palette: Palette, + /// Compacted list of indices pointing to entry IDs in the Palette. + data: Vec, +} + +pub enum Palette { + /// ID of the corresponding entry in its global palette + SingleValue(u32), + LinearPalette(Vec), + HashmapPalette(Vec), + GlobalPalette, +} + +impl Palette { + fn choose_palette_for_states(bits_per_entry: u8) -> &'static Palette { + match bits_per_entry { + 0 => &Palette::SingleValue, + 1..=4 => &Palette::LinearPalette, + 5..=8 => &Palette::HashmapPalette, + _ => &Palette::GlobalPalette, + } + } +} From a24d00d99819166a147af77dc50ff61dff5cb04a Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 1 May 2022 23:35:30 -0500 Subject: [PATCH 02/29] impl Write instead of Vec for consistency --- azalea-protocol/packet-macros/src/lib.rs | 8 +- azalea-protocol/src/mc_buf/mod.rs | 2 +- azalea-protocol/src/mc_buf/write.rs | 128 ++++++------------ .../clientbound_declare_commands_packet.rs | 11 +- .../clientbound_player_abilities_packet.rs | 5 +- .../game/clientbound_player_info_packet.rs | 4 +- .../clientbound_player_position_packet.rs | 5 +- .../packets/game/clientbound_recipe_packet.rs | 7 +- .../clientbound_set_entity_data_packet.rs | 9 +- .../clientbound_update_attributes_packet.rs | 4 +- .../game/clientbound_update_recipes_packet.rs | 6 +- .../game/clientbound_update_tags_packet.rs | 9 +- .../login/clientbound_game_profile_packet.rs | 4 +- .../packets/login/clientbound_hello_packet.rs | 9 +- .../clientbound_login_compression_packet.rs | 9 +- azalea-protocol/src/packets/mod.rs | 6 +- .../clientbound_status_response_packet.rs | 4 +- 17 files changed, 100 insertions(+), 130 deletions(-) diff --git a/azalea-protocol/packet-macros/src/lib.rs b/azalea-protocol/packet-macros/src/lib.rs index 0d912257..35abf642 100755 --- a/azalea-protocol/packet-macros/src/lib.rs +++ b/azalea-protocol/packet-macros/src/lib.rs @@ -123,7 +123,7 @@ fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt quote! { impl crate::mc_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { #(#write_fields)* Ok(()) } @@ -133,7 +133,7 @@ fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt syn::Data::Enum(syn::DataEnum { .. }) => { quote! { impl crate::mc_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { crate::mc_buf::Writable::write_varint(buf, *self as i32) } } @@ -178,7 +178,7 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke #state::#ident(self) } - pub fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { crate::mc_buf::McBufWritable::write_into(self, buf) } @@ -366,7 +366,7 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream { } } - fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { match self { #write_match_contents } diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs index a61ad3c3..a82334fb 100755 --- a/azalea-protocol/src/mc_buf/mod.rs +++ b/azalea-protocol/src/mc_buf/mod.rs @@ -5,7 +5,7 @@ mod write; use packet_macros::{McBufReadable, McBufWritable}; pub use read::{read_varint_async, McBufReadable, McBufVarintReadable, Readable}; -use std::ops::{Deref, Index}; +use std::ops::Deref; pub use write::{McBufVarintWritable, McBufWritable, Writable}; // const DEFAULT_NBT_QUOTA: u32 = 2097152; diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs index 57ec3a48..34bcafeb 100755 --- a/azalea-protocol/src/mc_buf/write.rs +++ b/azalea-protocol/src/mc_buf/write.rs @@ -8,49 +8,10 @@ use byteorder::{BigEndian, WriteBytesExt}; use std::io::Write; use uuid::Uuid; -pub trait Writable { +pub trait Writable: Write { fn write_list(&mut self, list: &[T], writer: F) -> Result<(), std::io::Error> where F: FnOnce(&mut Self, &T) -> Result<(), std::io::Error> + Copy, - T: Sized, - Self: Sized; - fn write_int_id_list(&mut self, list: &Vec) -> Result<(), std::io::Error>; - fn write_map( - &mut self, - map: Vec<(KT, VT)>, - key_writer: KF, - value_writer: VF, - ) -> Result<(), std::io::Error> - where - KF: Fn(&mut Self, KT) -> Result<(), std::io::Error> + Copy, - VF: Fn(&mut Self, VT) -> Result<(), std::io::Error> + Copy, - Self: Sized; - - fn write_byte(&mut self, n: u8) -> Result<(), std::io::Error>; - fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>; - fn write_varint(&mut self, value: i32) -> Result<(), std::io::Error>; - fn write_utf_with_len(&mut self, string: &str, len: usize) -> Result<(), std::io::Error>; - fn write_utf(&mut self, string: &str) -> Result<(), std::io::Error>; - fn write_short(&mut self, n: i16) -> Result<(), std::io::Error>; - fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>; - fn write_int(&mut self, n: i32) -> Result<(), std::io::Error>; - fn write_boolean(&mut self, b: bool) -> Result<(), std::io::Error>; - fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error>; - fn write_long(&mut self, n: i64) -> Result<(), std::io::Error>; - fn write_resource_location( - &mut self, - location: &ResourceLocation, - ) -> Result<(), std::io::Error>; - fn write_float(&mut self, n: f32) -> Result<(), std::io::Error>; - fn write_double(&mut self, n: f64) -> Result<(), std::io::Error>; - fn write_uuid(&mut self, uuid: &Uuid) -> Result<(), std::io::Error>; -} - -impl Writable for Vec { - fn write_list(&mut self, list: &[T], writer: F) -> Result<(), std::io::Error> - where - F: FnOnce(&mut Self, &T) -> Result<(), std::io::Error> + Copy, - Self: Sized, { self.write_varint(list.len() as i32)?; for item in list { @@ -72,7 +33,6 @@ impl Writable for Vec { where KF: Fn(&mut Self, KT) -> Result<(), std::io::Error> + Copy, VF: Fn(&mut Self, VT) -> Result<(), std::io::Error> + Copy, - Self: Sized, { self.write_varint(map.len() as i32)?; for (key, value) in map { @@ -87,7 +47,7 @@ impl Writable for Vec { } fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> { - self.extend_from_slice(bytes); + self.write_all(bytes); Ok(()) } @@ -140,7 +100,10 @@ impl Writable for Vec { self.write_byte(if b { 1 } else { 0 }) } - fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error> { + fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error> + where + Self: Sized, + { nbt.write(self) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) } @@ -164,7 +127,10 @@ impl Writable for Vec { self.write_utf(&location.to_string()) } - fn write_uuid(&mut self, uuid: &Uuid) -> Result<(), std::io::Error> { + fn write_uuid(&mut self, uuid: &Uuid) -> Result<(), std::io::Error> + where + Self: Sized, + { let [a, b, c, d] = uuid.to_int_array(); a.write_into(self)?; b.write_into(self)?; @@ -174,34 +140,30 @@ impl Writable for Vec { } } -pub trait McBufWritable -where - Self: Sized, -{ - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error>; +impl Writable for W {} + +pub trait McBufWritable { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } -pub trait McBufVarintWritable -where - Self: Sized, -{ - fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error>; +pub trait McBufVarintWritable { + fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } impl McBufWritable for i32 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { Writable::write_int(buf, *self) } } impl McBufVarintWritable for i32 { - fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(*self) } } impl McBufWritable for UnsizedByteArray { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_bytes(self) } } @@ -209,132 +171,132 @@ impl McBufWritable for UnsizedByteArray { // TODO: use specialization when that gets stabilized into rust // to optimize for Vec byte arrays impl McBufWritable for Vec { - default fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_list(self, |buf, i| T::write_into(i, buf)) } } impl McBufWritable for Vec { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte_array(self) } } // string impl McBufWritable for String { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_utf(self) } } // ResourceLocation impl McBufWritable for ResourceLocation { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_resource_location(self) } } // u32 impl McBufWritable for u32 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { i16::write_into(&(*self as i16), buf) } } // u32 varint impl McBufVarintWritable for u32 { - fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { i32::varint_write_into(&(*self as i32), buf) } } // u16 impl McBufWritable for u16 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { i16::write_into(&(*self as i16), buf) } } // u16 varint impl McBufVarintWritable for u16 { - fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { i32::varint_write_into(&(*self as i32), buf) } } // u8 impl McBufWritable for u8 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(*self) } } // i16 impl McBufWritable for i16 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { Writable::write_short(buf, *self) } } // i64 impl McBufWritable for i64 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { Writable::write_long(buf, *self) } } // u64 impl McBufWritable for u64 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { i64::write_into(&(*self as i64), buf) } } // bool impl McBufWritable for bool { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_boolean(*self) } } // i8 impl McBufWritable for i8 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(*self as u8) } } // f32 impl McBufWritable for f32 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_float(*self) } } // f64 impl McBufWritable for f64 { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_double(*self) } } // GameType impl McBufWritable for GameType { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { u8::write_into(&self.to_id(), buf) } } // Option impl McBufWritable for Option { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(GameType::to_optional_id(self) as u8) } } // Option impl McBufWritable for Option { - default fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { if let Some(s) = self { buf.write_boolean(true)?; s.write_into(buf)?; @@ -347,14 +309,14 @@ impl McBufWritable for Option { // azalea_nbt::Tag impl McBufWritable for azalea_nbt::Tag { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_nbt(self) } } // Difficulty impl McBufWritable for Difficulty { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { u8::write_into(&self.id(), buf) } } @@ -371,7 +333,7 @@ impl McBufWritable for Component { // let component = Component::deserialize(json).map_err(|e| e.to_string())?; // Ok(component) // } - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { // component doesn't have serialize implemented yet todo!() } @@ -379,7 +341,7 @@ impl McBufWritable for Component { // Slot impl McBufWritable for Slot { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { Slot::Empty => buf.write_byte(0)?, Slot::Present(i) => { @@ -395,7 +357,7 @@ impl McBufWritable for Slot { // Slot impl McBufWritable for Uuid { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_uuid(self)?; Ok(()) @@ -404,7 +366,7 @@ impl McBufWritable for Uuid { // BlockPos impl McBufWritable for BlockPos { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_long( (((self.x & 0x3FFFFFF) as i64) << 38) | (((self.z & 0x3FFFFFF) as i64) << 12) @@ -415,7 +377,7 @@ impl McBufWritable for BlockPos { // Direction impl McBufWritable for Direction { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(*self as i32) } } diff --git a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs index 703811c0..27f4fb16 100755 --- a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs @@ -1,7 +1,10 @@ use super::GamePacket; use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; -use std::{hash::Hash, io::Read}; +use std::{ + hash::Hash, + io::{Read, Write}, +}; #[derive(Hash, Clone, Debug)] pub struct ClientboundDeclareCommandsPacket { @@ -14,7 +17,7 @@ impl ClientboundDeclareCommandsPacket { GamePacket::ClientboundDeclareCommandsPacket(self) } - pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { panic!("ClientboundDeclareCommandsPacket::write not implemented") } @@ -60,7 +63,7 @@ impl McBufReadable for BrigadierNumber { } } impl McBufWritable for BrigadierNumber { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut flags = 0; if self.min.is_some() { flags |= 0x01; @@ -101,7 +104,7 @@ impl McBufReadable for BrigadierString { } } impl McBufWritable for BrigadierString { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(*self as u8)?; Ok(()) } diff --git a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs index 3ca1ac85..cd645fe6 100755 --- a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs @@ -1,7 +1,6 @@ -use std::io::Read; - use crate::mc_buf::{McBufReadable, McBufWritable, Readable}; use packet_macros::GamePacket; +use std::io::{Read, Write}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundPlayerAbilitiesPacket { @@ -32,7 +31,7 @@ impl McBufReadable for PlayerAbilitiesFlags { } impl McBufWritable for PlayerAbilitiesFlags { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut byte = 0; if self.invulnerable { byte = byte | 1; diff --git a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs index 97b68259..9c34d06e 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs @@ -1,7 +1,7 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_chat::component::Component; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; -use std::io::Read; +use std::io::{Read, Write}; use uuid::Uuid; #[derive(Clone, Debug, GamePacket)] @@ -75,7 +75,7 @@ impl McBufReadable for Action { } } impl McBufWritable for Action { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(match self { Action::AddPlayer(_) => 0, Action::UpdateGameMode(_) => 1, diff --git a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs index e47ca9e1..cac4665d 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs @@ -1,7 +1,6 @@ -use std::io::Read; - use crate::mc_buf::{McBufReadable, McBufWritable, Readable}; use packet_macros::GamePacket; +use std::io::{Read, Write}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundPlayerPositionPacket { @@ -41,7 +40,7 @@ impl McBufReadable for RelativeArguments { } impl McBufWritable for RelativeArguments { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut byte = 0; if self.x { byte = byte | 0b1; diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs index 4847bbf8..543fb64c 100644 --- a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs @@ -1,8 +1,7 @@ +use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::{resource_location::ResourceLocation, Slot}; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; -use std::io::Read; - -use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; +use std::io::{Read, Write}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundRecipePacket { @@ -35,7 +34,7 @@ pub enum State { } impl McBufWritable for State { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(*self as i32)?; Ok(()) } diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs index 302d832a..5d288518 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use crate::{ mc_buf::{Readable, Writable}, packets::{McBufReadable, McBufWritable}, @@ -7,6 +5,7 @@ use crate::{ use azalea_chat::component::Component; use azalea_core::{BlockPos, Direction, Slot}; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use std::io::{Read, Write}; use uuid::Uuid; #[derive(Clone, Debug, GamePacket)] @@ -40,7 +39,7 @@ impl McBufReadable for Vec { } impl McBufWritable for Vec { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for item in self { buf.write_byte(item.index)?; item.value.write_into(buf)?; @@ -124,7 +123,7 @@ impl McBufReadable for EntityDataValue { } impl McBufWritable for EntityDataValue { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { todo!(); } } @@ -399,7 +398,7 @@ impl McBufReadable for ParticleData { } impl McBufWritable for ParticleData { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { todo!() } } diff --git a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs index 6e0aae29..82f34f96 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs @@ -1,7 +1,7 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; -use std::io::Read; +use std::io::{Read, Write}; use uuid::Uuid; #[derive(Clone, Debug, GamePacket)] @@ -44,7 +44,7 @@ impl McBufReadable for Operation { } impl McBufWritable for Operation { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(*self as u8)?; Ok(()) } diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs index 4b1a322a..d15e10c3 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use std::io::{Read, Write}; use azalea_core::{resource_location::ResourceLocation, Slot}; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; @@ -35,7 +35,7 @@ pub struct ShapedRecipe { } impl McBufWritable for ShapedRecipe { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(self.width.try_into().unwrap())?; buf.write_varint(self.height.try_into().unwrap())?; buf.write_utf(&self.group)?; @@ -122,7 +122,7 @@ pub struct Ingredient { } impl McBufWritable for Recipe { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { todo!() } } diff --git a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs index 4646c2d3..f82a4177 100755 --- a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs @@ -1,7 +1,10 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; use packet_macros::GamePacket; -use std::{collections::HashMap, io::Read}; +use std::{ + collections::HashMap, + io::{Read, Write}, +}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundUpdateTagsPacket { @@ -33,7 +36,7 @@ impl McBufReadable for HashMap> { } impl McBufWritable for HashMap> { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(self.len() as i32)?; for (k, v) in self { k.write_into(buf)?; @@ -51,7 +54,7 @@ impl McBufReadable for Tags { } impl McBufWritable for Tags { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { self.name.write_into(buf)?; buf.write_int_id_list(&self.elements)?; Ok(()) diff --git a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs index bcdcd105..dd077ced 100755 --- a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs +++ b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use std::io::{Read, Write}; use super::LoginPacket; use crate::mc_buf::{Readable, Writable}; @@ -17,7 +17,7 @@ impl ClientboundGameProfilePacket { LoginPacket::ClientboundGameProfilePacket(self) } - pub fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for n in self.game_profile.uuid.to_int_array() { buf.write_int(n as i32).unwrap(); } diff --git a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs index 06f346c2..f7de4c21 100755 --- a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs +++ b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs @@ -1,4 +1,7 @@ -use std::{hash::Hash, io::Read}; +use std::{ + hash::Hash, + io::{Read, Write}, +}; use super::LoginPacket; use crate::mc_buf::Readable; @@ -15,11 +18,11 @@ impl ClientboundHelloPacket { LoginPacket::ClientboundHelloPacket(self) } - pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { panic!("ClientboundHelloPacket::write not implemented") } - pub fn read(buf: &mut impl Read) -> Result { + pub fn read(buf: &mut impl Read) -> Result { let server_id = buf.read_utf_with_len(20)?; let public_key = buf.read_byte_array()?; let nonce = buf.read_byte_array()?; diff --git a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs index a5ab78bb..b1323f50 100755 --- a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs +++ b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs @@ -1,4 +1,7 @@ -use std::{hash::Hash, io::Read}; +use std::{ + hash::Hash, + io::{Read, Write}, +}; use crate::mc_buf::{Readable, Writable}; @@ -14,12 +17,12 @@ impl ClientboundLoginCompressionPacket { LoginPacket::ClientboundLoginCompressionPacket(self) } - pub fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(self.compression_threshold).unwrap(); Ok(()) } - pub fn read(buf: &mut impl Read) -> Result { + pub fn read(buf: &mut impl Read) -> Result { let compression_threshold = buf.read_varint()?; Ok(ClientboundLoginCompressionPacket { diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs index 67fa92e9..a706646d 100755 --- a/azalea-protocol/src/packets/mod.rs +++ b/azalea-protocol/src/packets/mod.rs @@ -3,7 +3,7 @@ pub mod handshake; pub mod login; pub mod status; -use std::io::Read; +use std::io::{Read, Write}; use crate::{ connect::PacketFlow, @@ -40,7 +40,7 @@ where /// Read a packet by its id, ConnectionProtocol, and flow fn read(id: u32, flow: &PacketFlow, buf: &mut impl Read) -> Result; - fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error>; + fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } impl McBufReadable for ConnectionProtocol { @@ -51,7 +51,7 @@ impl McBufReadable for ConnectionProtocol { } impl McBufWritable for ConnectionProtocol { - fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_varint(*self as i32) } } diff --git a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs index f5789ae3..2acdb8c2 100755 --- a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs +++ b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use std::io::{Read, Write}; use azalea_chat::component::Component; use serde::Deserialize; @@ -41,7 +41,7 @@ impl ClientboundStatusResponsePacket { StatusPacket::ClientboundStatusResponsePacket(self) } - pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { + pub fn write(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { Ok(()) } From 1e2ec611003770ce889d69545604f164e2ea8fff Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 2 May 2022 00:24:29 -0500 Subject: [PATCH 03/29] write some more azalea-world code --- Cargo.lock | 3 + azalea-protocol/src/mc_buf/mod.rs | 6 + ...ientbound_level_chunk_with_light_packet.rs | 6 - azalea-world/Cargo.toml | 3 +- azalea-world/src/lib.rs | 120 ++++++++++++++++-- 5 files changed, 118 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f6ef343..b0fe3c05 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,6 +164,9 @@ dependencies = [ [[package]] name = "azalea-world" version = "0.1.0" +dependencies = [ + "azalea-protocol", +] [[package]] name = "bitflags" diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs index a82334fb..74d69441 100755 --- a/azalea-protocol/src/mc_buf/mod.rs +++ b/azalea-protocol/src/mc_buf/mod.rs @@ -1,5 +1,11 @@ //! Utilities for reading and writing for the Minecraft protocol +// TODO: have a separate azalea-protocol-definitions crate to house everything in mc_buf +// We need to do this to prevent cyclic dependencies. +// For example with azalea-protocol depending on azalea-world, +// it could be changed to azalea-protocol depending on azalea-world +// and azalea-world depending on azalea-protocol-definitions. + mod read; mod write; diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index abd936dc..0ab581ec 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -28,9 +28,3 @@ pub struct BlockEntity { } pub struct ChunkSection {} - -impl ClientboundLevelChunkPacketData { - pub fn read(world_height: u32) { - // let section_count - } -} diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml index afae93a7..54326fb7 100644 --- a/azalea-world/Cargo.toml +++ b/azalea-world/Cargo.toml @@ -1,8 +1,9 @@ [package] +edition = "2021" name = "azalea-world" version = "0.1.0" -edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +azalea-protocol = {path = "../azalea-protocol"} diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 20043bbf..e6b90ad5 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,3 +1,6 @@ +use azalea_protocol::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; +use std::io::{Read, Write}; + #[cfg(test)] mod tests { #[test] @@ -7,22 +10,92 @@ mod tests { } } +const SECTION_HEIGHT: u32 = 16; + pub struct Chunk { - sections: Vec
, + pub sections: Vec
, } +impl Chunk { + fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { + let section_count = world_height / SECTION_HEIGHT; + let mut sections = Vec::with_capacity(section_count as usize); + for _ in 0..section_count { + let section = Section::read_into(buf)?; + sections.push(section); + } + Ok(Chunk { sections }) + } +} + +impl McBufWritable for Chunk { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + for section in &self.sections { + section.write_into(buf)?; + } + Ok(()) + } +} + +#[derive(Clone, Debug)] pub struct Section { - states: PalettedContainer, - biomes: PalettedContainer, + pub block_count: u16, + pub states: PalettedContainer, + pub biomes: PalettedContainer, } +impl McBufReadable for Section { + fn read_into(buf: &mut impl Read) -> Result { + let block_count = u16::read_into(buf)?; + let states = PalettedContainer::read_into(buf)?; + let biomes = PalettedContainer::read_into(buf)?; + Ok(Section { + block_count, + states, + biomes, + }) + } +} + +impl McBufWritable for Section { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.block_count.write_into(buf)?; + self.states.write_into(buf)?; + self.biomes.write_into(buf)?; + Ok(()) + } +} + +#[derive(Clone, Debug)] pub struct PalettedContainer { - bits_per_entry: u8, - palette: Palette, + pub bits_per_entry: u8, + pub palette: Palette, /// Compacted list of indices pointing to entry IDs in the Palette. - data: Vec, + pub data: Vec, } +impl McBufReadable for PalettedContainer { + fn read_into(buf: &mut impl Read) -> Result { + let bits_per_entry = buf.read_byte()?; + let palette = Palette::read_with_bits_per_entry(buf, bits_per_entry)?; + let data = Vec::::read_into(buf)?; + Ok(PalettedContainer { + bits_per_entry, + palette, + data, + }) + } +} +impl McBufWritable for PalettedContainer { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + buf.write_byte(self.bits_per_entry)?; + self.palette.write_into(buf)?; + self.data.write_into(buf)?; + Ok(()) + } +} + +#[derive(Clone, Debug)] pub enum Palette { /// ID of the corresponding entry in its global palette SingleValue(u32), @@ -32,12 +105,33 @@ pub enum Palette { } impl Palette { - fn choose_palette_for_states(bits_per_entry: u8) -> &'static Palette { - match bits_per_entry { - 0 => &Palette::SingleValue, - 1..=4 => &Palette::LinearPalette, - 5..=8 => &Palette::HashmapPalette, - _ => &Palette::GlobalPalette, - } + pub fn read_with_bits_per_entry( + buf: &mut impl Read, + bits_per_entry: u8, + ) -> Result { + Ok(match bits_per_entry { + 0 => Palette::SingleValue(u32::read_into(buf)?), + 1..=4 => Palette::LinearPalette(Vec::::read_into(buf)?), + 5..=8 => Palette::HashmapPalette(Vec::::read_into(buf)?), + _ => Palette::GlobalPalette, + }) + } +} + +impl McBufWritable for Palette { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Palette::SingleValue(value) => { + value.write_into(buf)?; + } + Palette::LinearPalette(values) => { + values.write_into(buf)?; + } + Palette::HashmapPalette(values) => { + values.write_into(buf)?; + } + Palette::GlobalPalette => {} + } + Ok(()) } } From 8e42e1c5dfc54314585b564696044780e0407c2f Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 2 May 2022 23:07:06 +0000 Subject: [PATCH 04/29] more chunk and readme stuff --- Cargo.lock | 1 + README.md | 10 +++++++--- azalea-client/Cargo.toml | 1 + azalea-client/src/connect.rs | 3 ++- azalea-protocol/src/mc_buf/mod.rs | 6 ------ .../game/clientbound_level_chunk_with_light_packet.rs | 1 - azalea-world/src/lib.rs | 6 +++++- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0fe3c05..3633a1af 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,7 @@ dependencies = [ "azalea-core", "azalea-crypto", "azalea-protocol", + "azalea-world", "tokio", ] diff --git a/README.md b/README.md index 909ae47e..4c90ba42 100755 --- a/README.md +++ b/README.md @@ -1,20 +1,24 @@ # Azalea -A Rust crate for creating Minecraft bots. -

Azalea

+A Rust crate for creating Minecraft bots. + I named this Azalea because it sounds like a cool word and this is a cool library. This project was heavily inspired by PrismarineJS. +## Why + +I wanted a fun excuse to do something cool with Rust, and I also felt like I could do better than [Mineflayer](https://github.com/prismarinejs/mineflayer) in some areas. + ## Goals - Do everything a vanilla client can do - Be easy to use - Bypass most/all anticheats - Support the latest Minecraft version -- Be fast +- Be fast and memory efficient ## Example code diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml index 55caadeb..1156f8de 100755 --- a/azalea-client/Cargo.toml +++ b/azalea-client/Cargo.toml @@ -10,4 +10,5 @@ azalea-auth = {path = "../azalea-auth"} azalea-core = {path = "../azalea-core"} azalea-crypto = {path = "../azalea-crypto"} azalea-protocol = {path = "../azalea-protocol"} +azalea-world = {path = "../azalea-world"} tokio = {version = "1.18.0", features = ["sync"]} diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index b628051a..be268eee 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -13,6 +13,7 @@ use azalea_protocol::{ }, resolver, ServerAddress, }; +use azalea_world::Chunk; use std::sync::Arc; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::Mutex; @@ -233,7 +234,7 @@ impl Client { } GamePacket::ClientboundLevelChunkWithLightPacket(p) => { println!("Got chunk with light packet {} {}", p.x, p.z); - // p.chunk_data + // let chunk = Chunk::read_with_world_height(&mut p.chunk_data); } GamePacket::ClientboundLightUpdatePacket(p) => { println!("Got light update packet {:?}", p); diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs index 74d69441..a82334fb 100755 --- a/azalea-protocol/src/mc_buf/mod.rs +++ b/azalea-protocol/src/mc_buf/mod.rs @@ -1,11 +1,5 @@ //! Utilities for reading and writing for the Minecraft protocol -// TODO: have a separate azalea-protocol-definitions crate to house everything in mc_buf -// We need to do this to prevent cyclic dependencies. -// For example with azalea-protocol depending on azalea-world, -// it could be changed to azalea-protocol depending on azalea-world -// and azalea-world depending on azalea-protocol-definitions. - mod read; mod write; diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index 0ab581ec..6810ceb2 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -27,4 +27,3 @@ pub struct BlockEntity { data: azalea_nbt::Tag, } -pub struct ChunkSection {} diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index e6b90ad5..8e60a6d6 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -12,12 +12,16 @@ mod tests { const SECTION_HEIGHT: u32 = 16; +pub struct World { + +} + pub struct Chunk { pub sections: Vec
, } impl Chunk { - fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { + pub fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { let section_count = world_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); for _ in 0..section_count { From 0bd798045c4328208667df37348e9affb37e384f Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 00:33:32 -0500 Subject: [PATCH 05/29] more azalea-world stuff --- Cargo.lock | 2 + azalea-client/src/connect.rs | 48 +- azalea-client/src/player.rs | 1 + azalea-core/src/block_pos.rs | 6 - azalea-core/src/lib.rs | 4 +- azalea-core/src/position.rs | 24 + azalea-nbt/src/tag.rs | 6 + ...ientbound_level_chunk_with_light_packet.rs | 15 +- .../clientbound_set_chunk_cache_center.rs | 2 +- azalea-world/Cargo.toml | 2 + azalea-world/src/lib.rs | 189 +- azalea-world/src/palette.rs | 73 + bot/src/main.rs | 2 +- login.txt | 4245 +++++++++++++++++ 14 files changed, 4523 insertions(+), 96 deletions(-) delete mode 100644 azalea-core/src/block_pos.rs create mode 100644 azalea-core/src/position.rs create mode 100644 azalea-world/src/palette.rs create mode 100644 login.txt diff --git a/Cargo.lock b/Cargo.lock index 3633a1af..73a8dafd 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,6 +166,8 @@ dependencies = [ name = "azalea-world" version = "0.1.0" dependencies = [ + "azalea-core", + "azalea-nbt", "azalea-protocol", ] diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index be268eee..e4d7d7e5 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -1,5 +1,5 @@ use crate::Player; -use azalea_core::resource_location::ResourceLocation; +use azalea_core::{resource_location::ResourceLocation, ChunkPos}; use azalea_protocol::{ connect::{GameConnection, HandshakeConnection}, packets::{ @@ -13,8 +13,8 @@ use azalea_protocol::{ }, resolver, ServerAddress, }; -use azalea_world::Chunk; -use std::sync::Arc; +use azalea_world::{Chunk, ChunkStorage, World}; +use std::{fmt::Debug, ops::Deref, sync::Arc}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::Mutex; @@ -27,8 +27,8 @@ pub struct Account { #[derive(Default)] pub struct ClientState { - // placeholder pub player: Player, + pub world: Option, } /// A player that you can control that is currently in a Minecraft server. @@ -173,8 +173,31 @@ impl Client { match packet { GamePacket::ClientboundLoginPacket(p) => { println!("Got login packet {:?}", p); + std::fs::write("login.txt", format!("{:#?}", p)).expect("Unable to write file"); + + let mut state = state.lock().await; + state.player.entity.id = p.player_id; + let dimension_type = p + .dimension_type + .as_compound() + .expect("Dimension type is not compound") + .get("") + .expect("No \"\" tag") + .as_compound() + .expect("\"\" tag is not compound"); + let height = (*dimension_type + .get("height") + .expect("No height tag") + .as_int() + .expect("height tag is not int")) + .try_into() + .expect("height is not a u32"); + + state.world = Some(World { + height, + storage: ChunkStorage::new(16), + }); - state.lock().await.player.entity.id = p.player_id; conn.lock() .await .write( @@ -231,10 +254,25 @@ impl Client { } GamePacket::ClientboundSetChunkCacheCenterPacket(p) => { println!("Got chunk cache center packet {:?}", p); + state + .lock() + .await + .world + .as_mut() + .unwrap() + .update_view_center(&ChunkPos::new(p.x, p.z)); } GamePacket::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); + // println("chunk {:?}") + state + .lock() + .await + .world + .replace_with_packet_data(&pos, &mut p.chunk_data.data.as_slice()) + .unwrap(); } GamePacket::ClientboundLightUpdatePacket(p) => { println!("Got light update packet {:?}", p); diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index fc54ff93..70ac1c76 100644 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -1,4 +1,5 @@ use crate::Entity; +use azalea_world::World; #[derive(Default)] pub struct Player { diff --git a/azalea-core/src/block_pos.rs b/azalea-core/src/block_pos.rs deleted file mode 100644 index 96a234cb..00000000 --- a/azalea-core/src/block_pos.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[derive(Clone, Copy, Debug)] -pub struct BlockPos { - pub x: i32, - pub y: i32, - pub z: i32, -} diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs index c6b51cb1..6f0c25cc 100755 --- a/azalea-core/src/lib.rs +++ b/azalea-core/src/lib.rs @@ -8,8 +8,8 @@ pub mod serializable_uuid; mod slot; pub use slot::{Slot, SlotData}; -mod block_pos; -pub use block_pos::BlockPos; +mod position; +pub use position::{BlockPos, ChunkPos}; mod direction; pub use direction::Direction; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs new file mode 100644 index 00000000..aa82c1f9 --- /dev/null +++ b/azalea-core/src/position.rs @@ -0,0 +1,24 @@ +#[derive(Clone, Copy, Debug, Default)] +pub struct BlockPos { + pub x: i32, + pub y: i32, + pub z: i32, +} + +impl BlockPos { + pub fn new(x: i32, y: i32, z: i32) -> Self { + BlockPos { x, y, z } + } +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct ChunkPos { + pub x: i32, + pub z: i32, +} + +impl ChunkPos { + pub fn new(x: i32, z: i32) -> Self { + ChunkPos { x, z } + } +} diff --git a/azalea-nbt/src/tag.rs b/azalea-nbt/src/tag.rs index 61bd15ba..e2df08f7 100755 --- a/azalea-nbt/src/tag.rs +++ b/azalea-nbt/src/tag.rs @@ -17,6 +17,12 @@ pub enum Tag { LongArray(Vec), // 12 } +impl Default for Tag { + fn default() -> Self { + Tag::End + } +} + impl Tag { #[inline] pub fn id(&self) -> u8 { diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index 6810ceb2..1d4bf58c 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -12,18 +12,17 @@ pub struct ClientboundLevelChunkWithLightPacket { #[derive(Clone, Debug, McBufReadable, McBufWritable)] pub struct ClientboundLevelChunkPacketData { - heightmaps: azalea_nbt::Tag, + pub heightmaps: azalea_nbt::Tag, // we can't parse the data in azalea-protocol because it dependso on context from other packets - data: Vec, - block_entities: Vec, + pub data: Vec, + pub block_entities: Vec, } #[derive(Clone, Debug, McBufReadable, McBufWritable)] pub struct BlockEntity { - packed_xz: u8, - y: u16, + pub packed_xz: u8, + pub y: u16, #[varint] - type_: i32, - data: azalea_nbt::Tag, + pub type_: i32, + pub data: azalea_nbt::Tag, } - diff --git a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs index 482dc0c7..5b6de0c9 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs @@ -5,5 +5,5 @@ pub struct ClientboundSetChunkCacheCenterPacket { #[varint] pub x: i32, #[varint] - pub y: i32, + pub z: i32, } diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml index 54326fb7..e8d81ac3 100644 --- a/azalea-world/Cargo.toml +++ b/azalea-world/Cargo.toml @@ -6,4 +6,6 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +azalea-core = {path = "../azalea-core"} +azalea-nbt = {path = "../azalea-nbt"} azalea-protocol = {path = "../azalea-protocol"} diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 8e60a6d6..51bc0764 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,5 +1,13 @@ -use azalea_protocol::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; -use std::io::{Read, Write}; +mod palette; + +use azalea_core::ChunkPos; +use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; +use palette::PalettedContainer; +use std::{ + io::{Read, Write}, + ops::{Index, IndexMut}, + sync::{Arc, Mutex}, +}; #[cfg(test)] mod tests { @@ -13,14 +21,107 @@ mod tests { const SECTION_HEIGHT: u32 = 16; pub struct World { - + pub storage: ChunkStorage, + pub height: u32, } +impl World { + pub fn replace_with_packet_data( + &mut self, + pos: &ChunkPos, + data: &mut impl Read, + ) -> Result<(), String> { + if !self.storage.in_range(pos) { + println!( + "Ignoring chunk since it's not in the view range: {}, {}", + pos.x, pos.z + ); + return Ok(()); + } + let existing_chunk = &self.storage[pos]; + if let Some(existing_chunk) = existing_chunk { + existing_chunk + .lock() + .expect("Couldn't get lock on existing chunk") + .replace_with_packet_data(data)?; + } else { + let chunk = Arc::new(Mutex::new(Chunk::read_with_world(data, self)?)); + println!("Loaded chunk {:?}", chunk); + self.storage[pos] = Some(chunk); + } + + Ok(()) + } + + pub fn update_view_center(&mut self, pos: &ChunkPos) { + self.storage.view_center = *pos; + } +} + +pub struct ChunkStorage { + view_center: ChunkPos, + chunk_radius: u32, + view_range: u32, + // chunks is a list of size chunk_radius * chunk_radius + chunks: Vec>>>, +} + +// java moment +// it might be possible to replace this with just a modulo, but i copied java's floorMod just in case +fn floor_mod(x: i32, y: u32) -> u32 { + if x < 0 { + y - ((-x) as u32 % y) + } else { + x as u32 % y + } +} + +impl ChunkStorage { + pub fn new(chunk_radius: u32) -> Self { + let view_range = chunk_radius * 2 + 1; + ChunkStorage { + view_center: ChunkPos::new(0, 0), + chunk_radius, + view_range, + chunks: vec![None; (view_range * view_range) as usize], + } + } + + fn get_index(&self, chunk_pos: &ChunkPos) -> usize { + (floor_mod(chunk_pos.x, self.view_range) * self.view_range + + floor_mod(chunk_pos.z, self.view_range)) as usize + } + + pub fn in_range(&self, chunk_pos: &ChunkPos) -> bool { + (chunk_pos.x - self.view_center.x).unsigned_abs() <= self.chunk_radius + && (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius + } +} + +impl Index<&ChunkPos> for ChunkStorage { + type Output = Option>>; + + fn index(&self, pos: &ChunkPos) -> &Self::Output { + &self.chunks[self.get_index(pos)] + } +} +impl IndexMut<&ChunkPos> for ChunkStorage { + fn index_mut<'a>(&'a mut self, pos: &ChunkPos) -> &'a mut Self::Output { + let index = self.get_index(pos); + &mut self.chunks[index] + } +} + +#[derive(Debug)] pub struct Chunk { pub sections: Vec
, } impl Chunk { + pub fn read_with_world(buf: &mut impl Read, data: &World) -> Result { + Self::read_with_world_height(buf, data.height) + } + pub fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { let section_count = world_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); @@ -30,6 +131,18 @@ impl Chunk { } Ok(Chunk { sections }) } + + fn replace_with_packet_data(&mut self, data: &mut impl Read) -> Result<(), String> { + let section_count = self.sections.len(); + + // this should also replace block entities and set the heightmap + + for i in 0..section_count { + self.sections[i] = Section::read_into(data)?; + } + + Ok(()) + } } impl McBufWritable for Chunk { @@ -69,73 +182,3 @@ impl McBufWritable for Section { Ok(()) } } - -#[derive(Clone, Debug)] -pub struct PalettedContainer { - pub bits_per_entry: u8, - pub palette: Palette, - /// Compacted list of indices pointing to entry IDs in the Palette. - pub data: Vec, -} - -impl McBufReadable for PalettedContainer { - fn read_into(buf: &mut impl Read) -> Result { - let bits_per_entry = buf.read_byte()?; - let palette = Palette::read_with_bits_per_entry(buf, bits_per_entry)?; - let data = Vec::::read_into(buf)?; - Ok(PalettedContainer { - bits_per_entry, - palette, - data, - }) - } -} -impl McBufWritable for PalettedContainer { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - buf.write_byte(self.bits_per_entry)?; - self.palette.write_into(buf)?; - self.data.write_into(buf)?; - Ok(()) - } -} - -#[derive(Clone, Debug)] -pub enum Palette { - /// ID of the corresponding entry in its global palette - SingleValue(u32), - LinearPalette(Vec), - HashmapPalette(Vec), - GlobalPalette, -} - -impl Palette { - pub fn read_with_bits_per_entry( - buf: &mut impl Read, - bits_per_entry: u8, - ) -> Result { - Ok(match bits_per_entry { - 0 => Palette::SingleValue(u32::read_into(buf)?), - 1..=4 => Palette::LinearPalette(Vec::::read_into(buf)?), - 5..=8 => Palette::HashmapPalette(Vec::::read_into(buf)?), - _ => Palette::GlobalPalette, - }) - } -} - -impl McBufWritable for Palette { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - Palette::SingleValue(value) => { - value.write_into(buf)?; - } - Palette::LinearPalette(values) => { - values.write_into(buf)?; - } - Palette::HashmapPalette(values) => { - values.write_into(buf)?; - } - Palette::GlobalPalette => {} - } - Ok(()) - } -} diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs new file mode 100644 index 00000000..a8ec50c9 --- /dev/null +++ b/azalea-world/src/palette.rs @@ -0,0 +1,73 @@ +use std::io::{Read, Write}; + +use azalea_protocol::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; + +#[derive(Clone, Debug)] +pub struct PalettedContainer { + pub bits_per_entry: u8, + pub palette: Palette, + /// Compacted list of indices pointing to entry IDs in the Palette. + pub data: Vec, +} + +impl McBufReadable for PalettedContainer { + fn read_into(buf: &mut impl Read) -> Result { + let bits_per_entry = buf.read_byte()?; + let palette = Palette::read_with_bits_per_entry(buf, bits_per_entry)?; + let data = Vec::::read_into(buf)?; + Ok(PalettedContainer { + bits_per_entry, + palette, + data, + }) + } +} +impl McBufWritable for PalettedContainer { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + buf.write_byte(self.bits_per_entry)?; + self.palette.write_into(buf)?; + self.data.write_into(buf)?; + Ok(()) + } +} + +#[derive(Clone, Debug)] +pub enum Palette { + /// ID of the corresponding entry in its global palette + SingleValue(u32), + LinearPalette(Vec), + HashmapPalette(Vec), + GlobalPalette, +} + +impl Palette { + pub fn read_with_bits_per_entry( + buf: &mut impl Read, + bits_per_entry: u8, + ) -> Result { + Ok(match bits_per_entry { + 0 => Palette::SingleValue(u32::read_into(buf)?), + 1..=4 => Palette::LinearPalette(Vec::::read_into(buf)?), + 5..=8 => Palette::HashmapPalette(Vec::::read_into(buf)?), + _ => Palette::GlobalPalette, + }) + } +} + +impl McBufWritable for Palette { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Palette::SingleValue(value) => { + value.write_into(buf)?; + } + Palette::LinearPalette(values) => { + values.write_into(buf)?; + } + Palette::HashmapPalette(values) => { + values.write_into(buf)?; + } + Palette::GlobalPalette => {} + } + Ok(()) + } +} diff --git a/bot/src/main.rs b/bot/src/main.rs index 8314eb5c..6a2d5959 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -5,7 +5,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "172.23.192.1:58024"; + let address = "172.23.192.1:59152"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); diff --git a/login.txt b/login.txt new file mode 100644 index 00000000..15e011e3 --- /dev/null +++ b/login.txt @@ -0,0 +1,4245 @@ +ClientboundLoginPacket { + player_id: 26888, + hardcore: false, + game_type: CREATIVE, + previous_game_type: None, + levels: [ + minecraft:overworld, + minecraft:the_end, + minecraft:the_nether, + ], + registry_holder: Compound( + { + "": Compound( + { + "minecraft:worldgen/biome": Compound( + { + "type": String( + "minecraft:worldgen/biome", + ), + "value": List( + [ + Compound( + { + "element": Compound( + { + "precipitation": String( + "none", + ), + "temperature": Float( + 0.5, + ), + "category": String( + "none", + ), + "effects": Compound( + { + "sky_color": Int( + 8103167, + ), + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "downfall": Float( + 0.5, + ), + }, + ), + "name": String( + "minecraft:the_void", + ), + "id": Int( + 0, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:plains", + ), + "id": Int( + 1, + ), + "element": Compound( + { + "category": String( + "plains", + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7907327, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.8, + ), + "downfall": Float( + 0.4, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:sunflower_plains", + ), + "id": Int( + 2, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.4, + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + }, + ), + "sky_color": Int( + 7907327, + ), + }, + ), + "category": String( + "plains", + ), + "temperature": Float( + 0.8, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:snowy_plains", + ), + "element": Compound( + { + "category": String( + "icy", + ), + "temperature": Float( + 0.0, + ), + "precipitation": String( + "snow", + ), + "downfall": Float( + 0.5, + ), + "effects": Compound( + { + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8364543, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + }, + ), + "id": Int( + 3, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:ice_spikes", + ), + "element": Compound( + { + "precipitation": String( + "snow", + ), + "temperature": Float( + 0.0, + ), + "category": String( + "icy", + ), + "downfall": Float( + 0.5, + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 8364543, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + }, + ), + }, + ), + "id": Int( + 4, + ), + }, + ), + Compound( + { + "id": Int( + 5, + ), + "name": String( + "minecraft:desert", + ), + "element": Compound( + { + "category": String( + "desert", + ), + "temperature": Float( + 2.0, + ), + "downfall": Float( + 0.0, + ), + "precipitation": String( + "none", + ), + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "category": String( + "swamp", + ), + "effects": Compound( + { + "water_color": Int( + 6388580, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7907327, + ), + "grass_color_modifier": String( + "swamp", + ), + "foliage_color": Int( + 6975545, + ), + "water_fog_color": Int( + 2302743, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.8, + ), + "downfall": Float( + 0.9, + ), + }, + ), + "id": Int( + 6, + ), + "name": String( + "minecraft:swamp", + ), + }, + ), + Compound( + { + "id": Int( + 7, + ), + "element": Compound( + { + "temperature": Float( + 0.7, + ), + "category": String( + "forest", + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.8, + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 7972607, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + }, + ), + "name": String( + "minecraft:forest", + ), + }, + ), + Compound( + { + "id": Int( + 8, + ), + "element": Compound( + { + "effects": Compound( + { + "sky_color": Int( + 7972607, + ), + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "precipitation": String( + "rain", + ), + "category": String( + "forest", + ), + "temperature": Float( + 0.7, + ), + "downfall": Float( + 0.8, + ), + }, + ), + "name": String( + "minecraft:flower_forest", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:birch_forest", + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "sky_color": Int( + 8037887, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + "downfall": Float( + 0.6, + ), + "temperature": Float( + 0.6, + ), + "category": String( + "forest", + ), + }, + ), + "id": Int( + 9, + ), + }, + ), + Compound( + { + "id": Int( + 10, + ), + "element": Compound( + { + "downfall": Float( + 0.8, + ), + "precipitation": String( + "rain", + ), + "category": String( + "forest", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "grass_color_modifier": String( + "dark_forest", + ), + "sky_color": Int( + 7972607, + ), + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + }, + ), + "temperature": Float( + 0.7, + ), + }, + ), + "name": String( + "minecraft:dark_forest", + ), + }, + ), + Compound( + { + "id": Int( + 11, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.6, + ), + "temperature": Float( + 0.6, + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8037887, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "category": String( + "forest", + ), + }, + ), + "name": String( + "minecraft:old_growth_birch_forest", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:old_growth_pine_taiga", + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "category": String( + "taiga", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8168447, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + "temperature": Float( + 0.3, + ), + "downfall": Float( + 0.8, + ), + }, + ), + "id": Int( + 12, + ), + }, + ), + Compound( + { + "id": Int( + 13, + ), + "name": String( + "minecraft:old_growth_spruce_taiga", + ), + "element": Compound( + { + "category": String( + "taiga", + ), + "downfall": Float( + 0.8, + ), + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "sky_color": Int( + 8233983, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "temperature": Float( + 0.25, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:taiga", + ), + "id": Int( + 14, + ), + "element": Compound( + { + "temperature": Float( + 0.25, + ), + "downfall": Float( + 0.8, + ), + "precipitation": String( + "rain", + ), + "category": String( + "taiga", + ), + "effects": Compound( + { + "sky_color": Int( + 8233983, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 15, + ), + "element": Compound( + { + "downfall": Float( + 0.4, + ), + "temperature": Float( + -0.5, + ), + "effects": Compound( + { + "water_color": Int( + 4020182, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8625919, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "category": String( + "taiga", + ), + "precipitation": String( + "snow", + ), + }, + ), + "name": String( + "minecraft:snowy_taiga", + ), + }, + ), + Compound( + { + "element": Compound( + { + "temperature": Float( + 2.0, + ), + "downfall": Float( + 0.0, + ), + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + }, + ), + }, + ), + "precipitation": String( + "none", + ), + "category": String( + "savanna", + ), + }, + ), + "name": String( + "minecraft:savanna", + ), + "id": Int( + 16, + ), + }, + ), + Compound( + { + "id": Int( + 17, + ), + "name": String( + "minecraft:savanna_plateau", + ), + "element": Compound( + { + "downfall": Float( + 0.0, + ), + "category": String( + "savanna", + ), + "precipitation": String( + "none", + ), + "temperature": Float( + 2.0, + ), + "effects": Compound( + { + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 7254527, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 18, + ), + "name": String( + "minecraft:windswept_hills", + ), + "element": Compound( + { + "temperature": Float( + 0.2, + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.3, + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8233727, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + }, + ), + "category": String( + "extreme_hills", + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 19, + ), + "element": Compound( + { + "temperature": Float( + 0.2, + ), + "precipitation": String( + "rain", + ), + "category": String( + "extreme_hills", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 8233727, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + }, + ), + "downfall": Float( + 0.3, + ), + }, + ), + "name": String( + "minecraft:windswept_gravelly_hills", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:windswept_forest", + ), + "id": Int( + 20, + ), + "element": Compound( + { + "category": String( + "extreme_hills", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 8233727, + ), + }, + ), + "downfall": Float( + 0.3, + ), + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.2, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:windswept_savanna", + ), + "element": Compound( + { + "temperature": Float( + 2.0, + ), + "downfall": Float( + 0.0, + ), + "category": String( + "savanna", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "sky_color": Int( + 7254527, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + "precipitation": String( + "none", + ), + }, + ), + "id": Int( + 21, + ), + }, + ), + Compound( + { + "id": Int( + 22, + ), + "name": String( + "minecraft:jungle", + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.95, + ), + "downfall": Float( + 0.9, + ), + "category": String( + "jungle", + ), + "effects": Compound( + { + "sky_color": Int( + 7842047, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "temperature": Float( + 0.95, + ), + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7842047, + ), + }, + ), + "category": String( + "jungle", + ), + "downfall": Float( + 0.8, + ), + }, + ), + "id": Int( + 23, + ), + "name": String( + "minecraft:sparse_jungle", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:bamboo_jungle", + ), + "id": Int( + 24, + ), + "element": Compound( + { + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7842047, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "downfall": Float( + 0.9, + ), + "temperature": Float( + 0.95, + ), + "precipitation": String( + "rain", + ), + "category": String( + "jungle", + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:badlands", + ), + "id": Int( + 25, + ), + "element": Compound( + { + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "foliage_color": Int( + 10387789, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "grass_color": Int( + 9470285, + ), + }, + ), + "category": String( + "mesa", + ), + "precipitation": String( + "none", + ), + "downfall": Float( + 0.0, + ), + "temperature": Float( + 2.0, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:eroded_badlands", + ), + "id": Int( + 26, + ), + "element": Compound( + { + "downfall": Float( + 0.0, + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "grass_color": Int( + 9470285, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "foliage_color": Int( + 10387789, + ), + "sky_color": Int( + 7254527, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "precipitation": String( + "none", + ), + "category": String( + "mesa", + ), + "temperature": Float( + 2.0, + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "foliage_color": Int( + 10387789, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + }, + ), + "grass_color": Int( + 9470285, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "temperature": Float( + 2.0, + ), + "downfall": Float( + 0.0, + ), + "category": String( + "mesa", + ), + "precipitation": String( + "none", + ), + }, + ), + "name": String( + "minecraft:wooded_badlands", + ), + "id": Int( + 27, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:meadow", + ), + "id": Int( + 28, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.5, + ), + "effects": Compound( + { + "sky_color": Int( + 8103167, + ), + "water_color": Int( + 937679, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.meadow", + ), + "replace_current_music": Byte( + 0, + ), + "max_delay": Int( + 24000, + ), + "min_delay": Int( + 12000, + ), + }, + ), + }, + ), + "category": String( + "mountain", + ), + "downfall": Float( + 0.8, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:grove", + ), + "id": Int( + 29, + ), + "element": Compound( + { + "precipitation": String( + "snow", + ), + "effects": Compound( + { + "music": Compound( + { + "min_delay": Int( + 12000, + ), + "max_delay": Int( + 24000, + ), + "replace_current_music": Byte( + 0, + ), + "sound": String( + "minecraft:music.overworld.grove", + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "sky_color": Int( + 8495359, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "temperature": Float( + -0.2, + ), + "downfall": Float( + 0.8, + ), + "category": String( + "forest", + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "temperature": Float( + -0.3, + ), + "precipitation": String( + "snow", + ), + "category": String( + "mountain", + ), + "effects": Compound( + { + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.snowy_slopes", + ), + "min_delay": Int( + 12000, + ), + "max_delay": Int( + 24000, + ), + "replace_current_music": Byte( + 0, + ), + }, + ), + "sky_color": Int( + 8560639, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "water_color": Int( + 4159204, + ), + }, + ), + "downfall": Float( + 0.9, + ), + }, + ), + "name": String( + "minecraft:snowy_slopes", + ), + "id": Int( + 30, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:frozen_peaks", + ), + "id": Int( + 31, + ), + "element": Compound( + { + "category": String( + "mountain", + ), + "precipitation": String( + "snow", + ), + "downfall": Float( + 0.9, + ), + "temperature": Float( + -0.7, + ), + "effects": Compound( + { + "sky_color": Int( + 8756735, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.frozen_peaks", + ), + "min_delay": Int( + 12000, + ), + "replace_current_music": Byte( + 0, + ), + "max_delay": Int( + 24000, + ), + }, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:jagged_peaks", + ), + "id": Int( + 32, + ), + "element": Compound( + { + "precipitation": String( + "snow", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "music": Compound( + { + "replace_current_music": Byte( + 0, + ), + "max_delay": Int( + 24000, + ), + "sound": String( + "minecraft:music.overworld.jagged_peaks", + ), + "min_delay": Int( + 12000, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 8756735, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "temperature": Float( + -0.7, + ), + "downfall": Float( + 0.9, + ), + "category": String( + "mountain", + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 33, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.3, + ), + "temperature": Float( + 1.0, + ), + "category": String( + "mountain", + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.stony_peaks", + ), + "replace_current_music": Byte( + 0, + ), + "max_delay": Int( + 24000, + ), + "min_delay": Int( + 12000, + ), + }, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7776511, + ), + "water_color": Int( + 4159204, + ), + }, + ), + }, + ), + "name": String( + "minecraft:stony_peaks", + ), + }, + ), + Compound( + { + "id": Int( + 34, + ), + "element": Compound( + { + "temperature": Float( + 0.5, + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8103167, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + }, + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.5, + ), + "category": String( + "river", + ), + }, + ), + "name": String( + "minecraft:river", + ), + }, + ), + Compound( + { + "element": Compound( + { + "category": String( + "river", + ), + "precipitation": String( + "snow", + ), + "effects": Compound( + { + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "sky_color": Int( + 8364543, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 3750089, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "temperature": Float( + 0.0, + ), + "downfall": Float( + 0.5, + ), + }, + ), + "name": String( + "minecraft:frozen_river", + ), + "id": Int( + 35, + ), + }, + ), + Compound( + { + "id": Int( + 36, + ), + "name": String( + "minecraft:beach", + ), + "element": Compound( + { + "temperature": Float( + 0.8, + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.4, + ), + "category": String( + "beach", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 7907327, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "downfall": Float( + 0.3, + ), + "category": String( + "beach", + ), + "precipitation": String( + "snow", + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8364543, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4020182, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + }, + ), + "temperature": Float( + 0.05, + ), + }, + ), + "id": Int( + 37, + ), + "name": String( + "minecraft:snowy_beach", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:stony_shore", + ), + "element": Compound( + { + "temperature": Float( + 0.2, + ), + "category": String( + "beach", + ), + "downfall": Float( + 0.3, + ), + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "sky_color": Int( + 8233727, + ), + }, + ), + }, + ), + "id": Int( + 38, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:warm_ocean", + ), + "id": Int( + 39, + ), + "element": Compound( + { + "downfall": Float( + 0.5, + ), + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.5, + ), + "category": String( + "ocean", + ), + "effects": Compound( + { + "sky_color": Int( + 8103167, + ), + "water_color": Int( + 4445678, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + "water_fog_color": Int( + 270131, + ), + "fog_color": Int( + 12638463, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:lukewarm_ocean", + ), + "element": Compound( + { + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4566514, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 8103167, + ), + "water_fog_color": Int( + 267827, + ), + }, + ), + "temperature": Float( + 0.5, + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.5, + ), + "category": String( + "ocean", + ), + }, + ), + "id": Int( + 40, + ), + }, + ), + Compound( + { + "id": Int( + 41, + ), + "element": Compound( + { + "temperature": Float( + 0.5, + ), + "downfall": Float( + 0.5, + ), + "effects": Compound( + { + "sky_color": Int( + 8103167, + ), + "water_fog_color": Int( + 267827, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_color": Int( + 4566514, + ), + }, + ), + "precipitation": String( + "rain", + ), + "category": String( + "ocean", + ), + }, + ), + "name": String( + "minecraft:deep_lukewarm_ocean", + ), + }, + ), + Compound( + { + "element": Compound( + { + "category": String( + "ocean", + ), + "temperature": Float( + 0.5, + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8103167, + ), + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + }, + ), + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.5, + ), + }, + ), + "id": Int( + 42, + ), + "name": String( + "minecraft:ocean", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:deep_ocean", + ), + "id": Int( + 43, + ), + "element": Compound( + { + "downfall": Float( + 0.5, + ), + "effects": Compound( + { + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8103167, + ), + }, + ), + "category": String( + "ocean", + ), + "temperature": Float( + 0.5, + ), + "precipitation": String( + "rain", + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:cold_ocean", + ), + "element": Compound( + { + "temperature": Float( + 0.5, + ), + "downfall": Float( + 0.5, + ), + "precipitation": String( + "rain", + ), + "category": String( + "ocean", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8103167, + ), + "water_color": Int( + 4020182, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + }, + ), + }, + ), + "id": Int( + 44, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:deep_cold_ocean", + ), + "id": Int( + 45, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "downfall": Float( + 0.5, + ), + "temperature": Float( + 0.5, + ), + "category": String( + "ocean", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 8103167, + ), + "water_color": Int( + 4020182, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:frozen_ocean", + ), + "element": Compound( + { + "effects": Compound( + { + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "sky_color": Int( + 8364543, + ), + "water_color": Int( + 3750089, + ), + }, + ), + "precipitation": String( + "snow", + ), + "temperature": Float( + 0.0, + ), + "downfall": Float( + 0.5, + ), + "temperature_modifier": String( + "frozen", + ), + "category": String( + "ocean", + ), + }, + ), + "id": Int( + 46, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:deep_frozen_ocean", + ), + "id": Int( + 47, + ), + "element": Compound( + { + "temperature_modifier": String( + "frozen", + ), + "temperature": Float( + 0.5, + ), + "downfall": Float( + 0.5, + ), + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 12638463, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_color": Int( + 3750089, + ), + "sky_color": Int( + 8103167, + ), + }, + ), + "category": String( + "ocean", + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 48, + ), + "name": String( + "minecraft:mushroom_fields", + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 7842047, + ), + "fog_color": Int( + 12638463, + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "downfall": Float( + 1.0, + ), + "temperature": Float( + 0.9, + ), + "category": String( + "mushroom", + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:dripstone_caves", + ), + "id": Int( + 49, + ), + "element": Compound( + { + "precipitation": String( + "rain", + ), + "temperature": Float( + 0.8, + ), + "downfall": Float( + 0.4, + ), + "category": String( + "underground", + ), + "effects": Compound( + { + "sky_color": Int( + 7907327, + ), + "water_fog_color": Int( + 329011, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.dripstone_caves", + ), + "max_delay": Int( + 24000, + ), + "min_delay": Int( + 12000, + ), + "replace_current_music": Byte( + 0, + ), + }, + ), + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + }, + ), + }, + ), + }, + ), + Compound( + { + "element": Compound( + { + "downfall": Float( + 0.5, + ), + "temperature": Float( + 0.5, + ), + "category": String( + "underground", + ), + "effects": Compound( + { + "fog_color": Int( + 12638463, + ), + "water_color": Int( + 4159204, + ), + "sky_color": Int( + 8103167, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.overworld.lush_caves", + ), + "min_delay": Int( + 12000, + ), + "max_delay": Int( + 24000, + ), + "replace_current_music": Byte( + 0, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + }, + ), + }, + ), + "precipitation": String( + "rain", + ), + }, + ), + "id": Int( + 50, + ), + "name": String( + "minecraft:lush_caves", + ), + }, + ), + Compound( + { + "element": Compound( + { + "effects": Compound( + { + "music": Compound( + { + "max_delay": Int( + 24000, + ), + "sound": String( + "minecraft:music.nether.nether_wastes", + ), + "min_delay": Int( + 12000, + ), + "replace_current_music": Byte( + 0, + ), + }, + ), + "fog_color": Int( + 3344392, + ), + "sky_color": Int( + 7254527, + ), + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + "ambient_sound": String( + "minecraft:ambient.nether_wastes.loop", + ), + "additions_sound": Compound( + { + "sound": String( + "minecraft:ambient.nether_wastes.additions", + ), + "tick_chance": Double( + 0.0111, + ), + }, + ), + "mood_sound": Compound( + { + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.nether_wastes.mood", + ), + }, + ), + }, + ), + "temperature": Float( + 2.0, + ), + "precipitation": String( + "none", + ), + "category": String( + "nether", + ), + "downfall": Float( + 0.0, + ), + }, + ), + "id": Int( + 51, + ), + "name": String( + "minecraft:nether_wastes", + ), + }, + ), + Compound( + { + "element": Compound( + { + "downfall": Float( + 0.0, + ), + "category": String( + "nether", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 7254527, + ), + "fog_color": Int( + 1705242, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.warped_forest.mood", + ), + "block_search_extent": Int( + 8, + ), + "offset": Double( + 2.0, + ), + }, + ), + "music": Compound( + { + "sound": String( + "minecraft:music.nether.warped_forest", + ), + "replace_current_music": Byte( + 0, + ), + "min_delay": Int( + 12000, + ), + "max_delay": Int( + 24000, + ), + }, + ), + "water_color": Int( + 4159204, + ), + "additions_sound": Compound( + { + "sound": String( + "minecraft:ambient.warped_forest.additions", + ), + "tick_chance": Double( + 0.0111, + ), + }, + ), + "ambient_sound": String( + "minecraft:ambient.warped_forest.loop", + ), + "particle": Compound( + { + "options": Compound( + { + "type": String( + "minecraft:warped_spore", + ), + }, + ), + "probability": Float( + 0.01428, + ), + }, + ), + }, + ), + "temperature": Float( + 2.0, + ), + "precipitation": String( + "none", + ), + }, + ), + "id": Int( + 52, + ), + "name": String( + "minecraft:warped_forest", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:crimson_forest", + ), + "id": Int( + 53, + ), + "element": Compound( + { + "precipitation": String( + "none", + ), + "downfall": Float( + 0.0, + ), + "temperature": Float( + 2.0, + ), + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "water_color": Int( + 4159204, + ), + "particle": Compound( + { + "probability": Float( + 0.025, + ), + "options": Compound( + { + "type": String( + "minecraft:crimson_spore", + ), + }, + ), + }, + ), + "ambient_sound": String( + "minecraft:ambient.crimson_forest.loop", + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.crimson_forest.mood", + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "additions_sound": Compound( + { + "tick_chance": Double( + 0.0111, + ), + "sound": String( + "minecraft:ambient.crimson_forest.additions", + ), + }, + ), + "fog_color": Int( + 3343107, + ), + "music": Compound( + { + "max_delay": Int( + 24000, + ), + "sound": String( + "minecraft:music.nether.crimson_forest", + ), + "replace_current_music": Byte( + 0, + ), + "min_delay": Int( + 12000, + ), + }, + ), + }, + ), + "category": String( + "nether", + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:soul_sand_valley", + ), + "id": Int( + 54, + ), + "element": Compound( + { + "category": String( + "nether", + ), + "effects": Compound( + { + "sky_color": Int( + 7254527, + ), + "additions_sound": Compound( + { + "tick_chance": Double( + 0.0111, + ), + "sound": String( + "minecraft:ambient.soul_sand_valley.additions", + ), + }, + ), + "particle": Compound( + { + "options": Compound( + { + "type": String( + "minecraft:ash", + ), + }, + ), + "probability": Float( + 0.00625, + ), + }, + ), + "water_color": Int( + 4159204, + ), + "music": Compound( + { + "min_delay": Int( + 12000, + ), + "replace_current_music": Byte( + 0, + ), + "max_delay": Int( + 24000, + ), + "sound": String( + "minecraft:music.nether.soul_sand_valley", + ), + }, + ), + "fog_color": Int( + 1787717, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.soul_sand_valley.mood", + ), + }, + ), + "ambient_sound": String( + "minecraft:ambient.soul_sand_valley.loop", + ), + "water_fog_color": Int( + 329011, + ), + }, + ), + "precipitation": String( + "none", + ), + "downfall": Float( + 0.0, + ), + "temperature": Float( + 2.0, + ), + }, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:basalt_deltas", + ), + "element": Compound( + { + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "music": Compound( + { + "replace_current_music": Byte( + 0, + ), + "min_delay": Int( + 12000, + ), + "sound": String( + "minecraft:music.nether.basalt_deltas", + ), + "max_delay": Int( + 24000, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "particle": Compound( + { + "probability": Float( + 0.118093334, + ), + "options": Compound( + { + "type": String( + "minecraft:white_ash", + ), + }, + ), + }, + ), + "sky_color": Int( + 7254527, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.basalt_deltas.mood", + ), + }, + ), + "ambient_sound": String( + "minecraft:ambient.basalt_deltas.loop", + ), + "additions_sound": Compound( + { + "tick_chance": Double( + 0.0111, + ), + "sound": String( + "minecraft:ambient.basalt_deltas.additions", + ), + }, + ), + "fog_color": Int( + 6840176, + ), + }, + ), + "temperature": Float( + 2.0, + ), + "downfall": Float( + 0.0, + ), + "category": String( + "nether", + ), + "precipitation": String( + "none", + ), + }, + ), + "id": Int( + 55, + ), + }, + ), + Compound( + { + "id": Int( + 56, + ), + "element": Compound( + { + "precipitation": String( + "none", + ), + "temperature": Float( + 0.5, + ), + "effects": Compound( + { + "sky_color": Int( + 0, + ), + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "fog_color": Int( + 10518688, + ), + }, + ), + "category": String( + "the_end", + ), + "downfall": Float( + 0.5, + ), + }, + ), + "name": String( + "minecraft:the_end", + ), + }, + ), + Compound( + { + "element": Compound( + { + "temperature": Float( + 0.5, + ), + "downfall": Float( + 0.5, + ), + "precipitation": String( + "none", + ), + "category": String( + "the_end", + ), + "effects": Compound( + { + "water_fog_color": Int( + 329011, + ), + "water_color": Int( + 4159204, + ), + "fog_color": Int( + 10518688, + ), + "mood_sound": Compound( + { + "block_search_extent": Int( + 8, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + }, + ), + "sky_color": Int( + 0, + ), + }, + ), + }, + ), + "id": Int( + 57, + ), + "name": String( + "minecraft:end_highlands", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:end_midlands", + ), + "id": Int( + 58, + ), + "element": Compound( + { + "temperature": Float( + 0.5, + ), + "effects": Compound( + { + "fog_color": Int( + 10518688, + ), + "water_color": Int( + 4159204, + ), + "water_fog_color": Int( + 329011, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 0, + ), + }, + ), + "category": String( + "the_end", + ), + "precipitation": String( + "none", + ), + "downfall": Float( + 0.5, + ), + }, + ), + }, + ), + Compound( + { + "id": Int( + 59, + ), + "element": Compound( + { + "category": String( + "the_end", + ), + "precipitation": String( + "none", + ), + "downfall": Float( + 0.5, + ), + "effects": Compound( + { + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "sound": String( + "minecraft:ambient.cave", + ), + "offset": Double( + 2.0, + ), + "tick_delay": Int( + 6000, + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "sky_color": Int( + 0, + ), + "water_fog_color": Int( + 329011, + ), + "fog_color": Int( + 10518688, + ), + }, + ), + "temperature": Float( + 0.5, + ), + }, + ), + "name": String( + "minecraft:small_end_islands", + ), + }, + ), + Compound( + { + "name": String( + "minecraft:end_barrens", + ), + "id": Int( + 60, + ), + "element": Compound( + { + "precipitation": String( + "none", + ), + "effects": Compound( + { + "fog_color": Int( + 10518688, + ), + "water_color": Int( + 4159204, + ), + "mood_sound": Compound( + { + "tick_delay": Int( + 6000, + ), + "offset": Double( + 2.0, + ), + "sound": String( + "minecraft:ambient.cave", + ), + "block_search_extent": Int( + 8, + ), + }, + ), + "water_fog_color": Int( + 329011, + ), + "sky_color": Int( + 0, + ), + }, + ), + "downfall": Float( + 0.5, + ), + "temperature": Float( + 0.5, + ), + "category": String( + "the_end", + ), + }, + ), + }, + ), + ], + ), + }, + ), + "minecraft:dimension_type": Compound( + { + "type": String( + "minecraft:dimension_type", + ), + "value": List( + [ + Compound( + { + "name": String( + "minecraft:overworld", + ), + "element": Compound( + { + "ambient_light": Float( + 0.0, + ), + "effects": String( + "minecraft:overworld", + ), + "min_y": Int( + -64, + ), + "bed_works": Byte( + 1, + ), + "has_raids": Byte( + 1, + ), + "height": Int( + 384, + ), + "natural": Byte( + 1, + ), + "has_ceiling": Byte( + 0, + ), + "has_skylight": Byte( + 1, + ), + "respawn_anchor_works": Byte( + 0, + ), + "coordinate_scale": Double( + 1.0, + ), + "ultrawarm": Byte( + 0, + ), + "piglin_safe": Byte( + 0, + ), + "infiniburn": String( + "#minecraft:infiniburn_overworld", + ), + "logical_height": Int( + 384, + ), + }, + ), + "id": Int( + 0, + ), + }, + ), + Compound( + { + "name": String( + "minecraft:overworld_caves", + ), + "element": Compound( + { + "piglin_safe": Byte( + 0, + ), + "has_ceiling": Byte( + 1, + ), + "has_raids": Byte( + 1, + ), + "effects": String( + "minecraft:overworld", + ), + "infiniburn": String( + "#minecraft:infiniburn_overworld", + ), + "min_y": Int( + -64, + ), + "has_skylight": Byte( + 1, + ), + "ultrawarm": Byte( + 0, + ), + "logical_height": Int( + 384, + ), + "coordinate_scale": Double( + 1.0, + ), + "ambient_light": Float( + 0.0, + ), + "respawn_anchor_works": Byte( + 0, + ), + "bed_works": Byte( + 1, + ), + "height": Int( + 384, + ), + "natural": Byte( + 1, + ), + }, + ), + "id": Int( + 1, + ), + }, + ), + Compound( + { + "id": Int( + 2, + ), + "element": Compound( + { + "respawn_anchor_works": Byte( + 1, + ), + "infiniburn": String( + "#minecraft:infiniburn_nether", + ), + "ambient_light": Float( + 0.1, + ), + "has_skylight": Byte( + 0, + ), + "fixed_time": Long( + 18000, + ), + "bed_works": Byte( + 0, + ), + "effects": String( + "minecraft:the_nether", + ), + "coordinate_scale": Double( + 8.0, + ), + "logical_height": Int( + 128, + ), + "has_raids": Byte( + 0, + ), + "height": Int( + 256, + ), + "min_y": Int( + 0, + ), + "natural": Byte( + 0, + ), + "has_ceiling": Byte( + 1, + ), + "piglin_safe": Byte( + 1, + ), + "ultrawarm": Byte( + 1, + ), + }, + ), + "name": String( + "minecraft:the_nether", + ), + }, + ), + Compound( + { + "id": Int( + 3, + ), + "name": String( + "minecraft:the_end", + ), + "element": Compound( + { + "height": Int( + 256, + ), + "logical_height": Int( + 256, + ), + "ambient_light": Float( + 0.0, + ), + "natural": Byte( + 0, + ), + "has_ceiling": Byte( + 0, + ), + "respawn_anchor_works": Byte( + 0, + ), + "min_y": Int( + 0, + ), + "piglin_safe": Byte( + 0, + ), + "has_skylight": Byte( + 0, + ), + "bed_works": Byte( + 0, + ), + "infiniburn": String( + "#minecraft:infiniburn_end", + ), + "effects": String( + "minecraft:the_end", + ), + "fixed_time": Long( + 6000, + ), + "has_raids": Byte( + 1, + ), + "coordinate_scale": Double( + 1.0, + ), + "ultrawarm": Byte( + 0, + ), + }, + ), + }, + ), + ], + ), + }, + ), + }, + ), + }, + ), + dimension_type: Compound( + { + "": Compound( + { + "coordinate_scale": Double( + 1.0, + ), + "ambient_light": Float( + 0.0, + ), + "effects": String( + "minecraft:overworld", + ), + "min_y": Int( + -64, + ), + "ultrawarm": Byte( + 0, + ), + "has_skylight": Byte( + 1, + ), + "bed_works": Byte( + 1, + ), + "logical_height": Int( + 384, + ), + "natural": Byte( + 1, + ), + "has_raids": Byte( + 1, + ), + "piglin_safe": Byte( + 0, + ), + "respawn_anchor_works": Byte( + 0, + ), + "has_ceiling": Byte( + 0, + ), + "infiniburn": String( + "#minecraft:infiniburn_overworld", + ), + "height": Int( + 384, + ), + }, + ), + }, + ), + dimension: minecraft:overworld, + seed: -8740116197493662413, + max_players: 8, + chunk_radius: 8, + simulation_distance: 5, + reduced_debug_info: false, + show_death_screen: true, + is_debug: false, + is_flat: false, +} \ No newline at end of file From 477c367fc44a2b5c139845f7e8307c6c276d95ee Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 18:03:10 +0000 Subject: [PATCH 06/29] mor echunk stuff --- azalea-client/src/connect.rs | 2 ++ azalea-protocol/README.md | 4 ++-- azalea-world/src/lib.rs | 28 +++++----------------------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index e4d7d7e5..984c5d86 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -271,6 +271,8 @@ impl Client { .lock() .await .world + .as_mut() + .expect("World doesn't exist! We should've gotten a login packet by now.") .replace_with_packet_data(&pos, &mut p.chunk_data.data.as_slice()) .unwrap(); } diff --git a/azalea-protocol/README.md b/azalea-protocol/README.md index 99b8b8d2..0321c7a5 100755 --- a/azalea-protocol/README.md +++ b/azalea-protocol/README.md @@ -2,8 +2,8 @@ Sent and receive Minecraft packets. You should probably use `azalea` or `azalea-client` instead. -The goal is to **only** support the latest Minecraft version in order to ease development. +The goal is to only support the latest Minecraft version in order to ease development. This is not yet complete, search for `TODO` in the code for things that need to be done. -Unfortunately, compiling the crate requires Rust nightly because specialization is not stable yet. +Unfortunately, using azalea-protocol requires Rust nightly because [specialization](https://github.com/rust-lang/rust/issues/31844) is not stable yet. Use `rustup default nightly` to enable it. diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 51bc0764..ea7798f8 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -38,17 +38,11 @@ impl World { ); return Ok(()); } - let existing_chunk = &self.storage[pos]; - if let Some(existing_chunk) = existing_chunk { - existing_chunk - .lock() - .expect("Couldn't get lock on existing chunk") - .replace_with_packet_data(data)?; - } else { - let chunk = Arc::new(Mutex::new(Chunk::read_with_world(data, self)?)); - println!("Loaded chunk {:?}", chunk); - self.storage[pos] = Some(chunk); - } + // let existing_chunk = &self.storage[pos]; + + let chunk = Arc::new(Mutex::new(Chunk::read_with_world(data, self)?)); + println!("Loaded chunk {:?}", chunk); + self.storage[pos] = Some(chunk); Ok(()) } @@ -131,18 +125,6 @@ impl Chunk { } Ok(Chunk { sections }) } - - fn replace_with_packet_data(&mut self, data: &mut impl Read) -> Result<(), String> { - let section_count = self.sections.len(); - - // this should also replace block entities and set the heightmap - - for i in 0..section_count { - self.sections[i] = Section::read_into(data)?; - } - - Ok(()) - } } impl McBufWritable for Chunk { From c9878129274258a30dc3ee0ecbd064b4fcf9bc6e Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 18:20:24 +0000 Subject: [PATCH 07/29] clippy --- azalea-client/src/connect.rs | 19 +++++++++---------- azalea-client/src/player.rs | 1 - azalea-crypto/src/lib.rs | 14 +++++--------- azalea-nbt/src/encode.rs | 2 +- azalea-protocol/packet-macros/src/lib.rs | 13 ++++++------- azalea-protocol/src/mc_buf/read.rs | 6 +++--- azalea-protocol/src/mc_buf/write.rs | 8 ++++---- .../clientbound_declare_commands_packet.rs | 18 ++++++++---------- .../game/clientbound_light_update_packet.rs | 1 - .../clientbound_player_abilities_packet.rs | 8 ++++---- .../clientbound_player_position_packet.rs | 10 +++++----- .../packets/game/clientbound_recipe_packet.rs | 4 ++-- .../clientbound_set_entity_data_packet.rs | 4 ++-- .../game/clientbound_update_recipes_packet.rs | 2 +- .../packets/login/serverbound_key_packet.rs | 2 -- azalea-protocol/src/write.rs | 5 +---- azalea-world/src/palette.rs | 18 +++++++++--------- 17 files changed, 60 insertions(+), 75 deletions(-) diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 984c5d86..3b880ea3 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -13,8 +13,8 @@ use azalea_protocol::{ }, resolver, ServerAddress, }; -use azalea_world::{Chunk, ChunkStorage, World}; -use std::{fmt::Debug, ops::Deref, sync::Arc}; +use azalea_world::{ChunkStorage, World}; +use std::{fmt::Debug, sync::Arc}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::Mutex; @@ -34,8 +34,8 @@ pub struct ClientState { /// A player that you can control that is currently in a Minecraft server. pub struct Client { event_receiver: UnboundedReceiver, - conn: Arc>, - state: Arc>, + pub conn: Arc>, + pub state: Arc>, // game_loop } @@ -133,10 +133,9 @@ impl Client { // just start up the game loop and we're ready! // tokio::spawn(Self::game_loop(conn, tx, handler, state)) - let game_loop_conn = conn.clone(); let game_loop_state = client.state.clone(); - tokio::spawn(Self::game_loop(game_loop_conn, tx, game_loop_state)); + tokio::spawn(Self::game_loop(conn, tx, game_loop_state)); Ok(client) } @@ -221,7 +220,7 @@ impl Client { GamePacket::ClientboundChangeDifficultyPacket(p) => { println!("Got difficulty packet {:?}", p); } - GamePacket::ClientboundDeclareCommandsPacket(p) => { + GamePacket::ClientboundDeclareCommandsPacket(_p) => { println!("Got declare commands packet"); } GamePacket::ClientboundPlayerAbilitiesPacket(p) => { @@ -230,19 +229,19 @@ impl Client { GamePacket::ClientboundSetCarriedItemPacket(p) => { println!("Got set carried item packet {:?}", p); } - GamePacket::ClientboundUpdateTagsPacket(p) => { + GamePacket::ClientboundUpdateTagsPacket(_p) => { println!("Got update tags packet"); } GamePacket::ClientboundDisconnectPacket(p) => { println!("Got disconnect packet {:?}", p); } - GamePacket::ClientboundUpdateRecipesPacket(p) => { + GamePacket::ClientboundUpdateRecipesPacket(_p) => { println!("Got update recipes packet"); } GamePacket::ClientboundEntityEventPacket(p) => { println!("Got entity event packet {:?}", p); } - GamePacket::ClientboundRecipePacket(p) => { + GamePacket::ClientboundRecipePacket(_p) => { println!("Got recipe packet"); } GamePacket::ClientboundPlayerPositionPacket(p) => { diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index 70ac1c76..fc54ff93 100644 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -1,5 +1,4 @@ use crate::Entity; -use azalea_world::World; #[derive(Default)] pub struct Player { diff --git a/azalea-crypto/src/lib.rs b/azalea-crypto/src/lib.rs index dc2620cc..62a81de3 100644 --- a/azalea-crypto/src/lib.rs +++ b/azalea-crypto/src/lib.rs @@ -1,9 +1,6 @@ use aes::cipher::inout::InOutBuf; -use aes::cipher::BlockEncrypt; use aes::{ - cipher::{ - generic_array::GenericArray, AsyncStreamCipher, BlockDecryptMut, BlockEncryptMut, KeyIvInit, - }, + cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit}, Aes128, }; use rand::{rngs::OsRng, RngCore}; @@ -15,7 +12,7 @@ fn generate_secret_key() -> [u8; 16] { key } -fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec { +pub fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec { let mut digest = Sha1::new(); digest.update(server_id); digest.update(public_key); @@ -23,7 +20,7 @@ fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec String { +pub fn hex_digest(digest: &[u8]) -> String { // Note that the Sha1.hexdigest() method used by minecraft is non standard. // It doesn't match the digest method found in most programming languages // and libraries. It works by treating the sha1 output bytes as one large @@ -48,9 +45,8 @@ pub fn encrypt(public_key: &[u8], nonce: &[u8]) -> Result // this.keybytes = Crypt.encryptUsingKey(publicKey, secretKey.getEncoded()); // this.nonce = Crypt.encryptUsingKey(publicKey, arrby); - let encrypted_public_key: Vec = - rsa_public_encrypt_pkcs1::encrypt(&public_key, &secret_key)?; - let encrypted_nonce: Vec = rsa_public_encrypt_pkcs1::encrypt(&public_key, &nonce)?; + let encrypted_public_key: Vec = rsa_public_encrypt_pkcs1::encrypt(public_key, &secret_key)?; + let encrypted_nonce: Vec = rsa_public_encrypt_pkcs1::encrypt(public_key, nonce)?; Ok(EncryptResult { secret_key, diff --git a/azalea-nbt/src/encode.rs b/azalea-nbt/src/encode.rs index 20d13793..fb5585b3 100755 --- a/azalea-nbt/src/encode.rs +++ b/azalea-nbt/src/encode.rs @@ -98,7 +98,7 @@ fn write_compound( if end_tag { writer.write_u8(Tag::End.id())?; } - return Ok(()); + Ok(()) } #[inline] diff --git a/azalea-protocol/packet-macros/src/lib.rs b/azalea-protocol/packet-macros/src/lib.rs index 35abf642..dec153ec 100755 --- a/azalea-protocol/packet-macros/src/lib.rs +++ b/azalea-protocol/packet-macros/src/lib.rs @@ -232,13 +232,12 @@ struct PacketIdMap { impl Parse for PacketIdMap { fn parse(input: ParseStream) -> Result { let mut packets = vec![]; - loop { - // 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, - // 0x0e - let packet_id: LitInt = match input.parse() { - Ok(i) => i, - Err(_) => break, - }; + + // example: + // 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, + + // 0x0e + while let Ok(packet_id) = input.parse::() { let packet_id = packet_id.base10_parse::()?; // : input.parse::()?; diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs index 68c9cb3f..e1ae321c 100755 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -1,10 +1,10 @@ -use super::{BitSet, UnsizedByteArray, MAX_STRING_LENGTH}; +use super::{UnsizedByteArray, MAX_STRING_LENGTH}; use azalea_chat::component::Component; use azalea_core::{ difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, serializable_uuid::SerializableUuid, BlockPos, Direction, Slot, SlotData, }; -use byteorder::{ReadBytesExt, WriteBytesExt, BE}; +use byteorder::{ReadBytesExt, BE}; use serde::Deserialize; use std::io::Read; use tokio::io::{AsyncRead, AsyncReadExt}; @@ -421,7 +421,7 @@ impl McBufReadable for Component { fn read_into(buf: &mut impl Read) -> Result { let string = buf.read_utf()?; let json: serde_json::Value = serde_json::from_str(string.as_str()) - .map_err(|e| "Component isn't valid JSON".to_string())?; + .map_err(|_| "Component isn't valid JSON".to_string())?; let component = Component::deserialize(json).map_err(|e| e.to_string())?; Ok(component) } diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs index 34bcafeb..3a4a02f8 100755 --- a/azalea-protocol/src/mc_buf/write.rs +++ b/azalea-protocol/src/mc_buf/write.rs @@ -20,8 +20,8 @@ pub trait Writable: Write { Ok(()) } - fn write_int_id_list(&mut self, list: &Vec) -> Result<(), std::io::Error> { - self.write_list(&list, |buf, n| buf.write_varint(*n)) + fn write_int_id_list(&mut self, list: &[i32]) -> Result<(), std::io::Error> { + self.write_list(list, |buf, n| buf.write_varint(*n)) } fn write_map( @@ -47,7 +47,7 @@ pub trait Writable: Write { } fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> { - self.write_all(bytes); + self.write_all(bytes)?; Ok(()) } @@ -333,7 +333,7 @@ impl McBufWritable for Component { // let component = Component::deserialize(json).map_err(|e| e.to_string())?; // Ok(component) // } - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { // component doesn't have serialize implemented yet todo!() } diff --git a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs index 27f4fb16..6743c3af 100755 --- a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs @@ -281,7 +281,7 @@ impl McBufReadable for BrigadierParser { } } -// azalea_brigadier::tree::CommandNode +// TODO: BrigadierNodeStub should have more stuff impl McBufReadable for BrigadierNodeStub { fn read_into(buf: &mut impl Read) -> Result { let flags = u8::read_into(buf)?; @@ -292,20 +292,18 @@ impl McBufReadable for BrigadierNodeStub { } let node_type = flags & 0x03; - let is_executable = flags & 0x04 != 0; + let _is_executable = flags & 0x04 != 0; let has_redirect = flags & 0x08 != 0; let has_suggestions_type = flags & 0x10 != 0; - let children = buf.read_int_id_list()?; - let redirect_node = if has_redirect { buf.read_varint()? } else { 0 }; + let _children = buf.read_int_id_list()?; + let _redirect_node = if has_redirect { buf.read_varint()? } else { 0 }; // argument node if node_type == 2 { - let name = buf.read_utf()?; - - let parser = BrigadierParser::read_into(buf)?; - - let suggestions_type = if has_suggestions_type { + let _name = buf.read_utf()?; + let _parser = BrigadierParser::read_into(buf)?; + let _suggestions_type = if has_suggestions_type { Some(buf.read_resource_location()?) } else { None @@ -314,7 +312,7 @@ impl McBufReadable for BrigadierNodeStub { } // literal node if node_type == 1 { - let name = buf.read_utf()?; + let _name = buf.read_utf()?; return Ok(BrigadierNodeStub {}); } Ok(BrigadierNodeStub {}) diff --git a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs index c97eacff..e83d1e87 100644 --- a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs @@ -1,5 +1,4 @@ use crate::mc_buf::BitSet; -use azalea_core::{game_type::GameType, resource_location::ResourceLocation}; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; #[derive(Clone, Debug, GamePacket)] diff --git a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs index cd645fe6..ed27ecf3 100755 --- a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs @@ -34,16 +34,16 @@ impl McBufWritable for PlayerAbilitiesFlags { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut byte = 0; if self.invulnerable { - byte = byte | 1; + byte |= 0b1; } if self.flying { - byte = byte | 2; + byte |= 0b10; } if self.can_fly { - byte = byte | 4; + byte |= 0b100; } if self.instant_break { - byte = byte | 8; + byte |= 0b1000; } u8::write_into(&byte, buf) } diff --git a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs index cac4665d..c2bef8fa 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs @@ -43,19 +43,19 @@ impl McBufWritable for RelativeArguments { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut byte = 0; if self.x { - byte = byte | 0b1; + byte |= 0b1; } if self.y { - byte = byte | 0b10; + byte |= 0b10; } if self.z { - byte = byte | 0b100; + byte |= 0b100; } if self.y_rot { - byte = byte | 0b1000; + byte |= 0b1000; } if self.x_rot { - byte = byte | 0b10000; + byte |= 0b10000; } u8::write_into(&byte, buf) } diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs index 543fb64c..fa0d58f0 100644 --- a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs @@ -1,5 +1,5 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; -use azalea_core::{resource_location::ResourceLocation, Slot}; +use azalea_core::resource_location::ResourceLocation; use packet_macros::{GamePacket, McBufReadable, McBufWritable}; use std::io::{Read, Write}; @@ -41,7 +41,7 @@ impl McBufWritable for State { } impl McBufReadable for State { fn read_into(buf: &mut impl Read) -> Result { - let state = buf.read_varint()?.try_into().unwrap(); + let state = buf.read_varint()?; Ok(match state { 0 => State::Init, 1 => State::Add, diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs index 5d288518..ca726c39 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs @@ -123,7 +123,7 @@ impl McBufReadable for EntityDataValue { } impl McBufWritable for EntityDataValue { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { todo!(); } } @@ -398,7 +398,7 @@ impl McBufReadable for ParticleData { } impl McBufWritable for ParticleData { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { todo!() } } diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs index d15e10c3..9bdea26e 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs @@ -122,7 +122,7 @@ pub struct Ingredient { } impl McBufWritable for Recipe { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> { todo!() } } diff --git a/azalea-protocol/src/packets/login/serverbound_key_packet.rs b/azalea-protocol/src/packets/login/serverbound_key_packet.rs index f402d357..2ff8dda6 100644 --- a/azalea-protocol/src/packets/login/serverbound_key_packet.rs +++ b/azalea-protocol/src/packets/login/serverbound_key_packet.rs @@ -1,5 +1,3 @@ -use super::LoginPacket; -use crate::mc_buf::Writable; use packet_macros::LoginPacket; use std::hash::Hash; diff --git a/azalea-protocol/src/write.rs b/azalea-protocol/src/write.rs index 345829c5..9291681c 100755 --- a/azalea-protocol/src/write.rs +++ b/azalea-protocol/src/write.rs @@ -2,10 +2,7 @@ use crate::{mc_buf::Writable, packets::ProtocolPacket, read::MAXIMUM_UNCOMPRESSE use async_compression::tokio::bufread::ZlibEncoder; use azalea_crypto::Aes128CfbEnc; use std::fmt::Debug; -use tokio::{ - io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}, - net::TcpStream, -}; +use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; fn frame_prepender(data: &mut Vec) -> Result, String> { let mut buf = Vec::new(); diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index a8ec50c9..69900fe6 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -35,9 +35,9 @@ impl McBufWritable for PalettedContainer { pub enum Palette { /// ID of the corresponding entry in its global palette SingleValue(u32), - LinearPalette(Vec), - HashmapPalette(Vec), - GlobalPalette, + Linear(Vec), + Hashmap(Vec), + Global, } impl Palette { @@ -47,9 +47,9 @@ impl Palette { ) -> Result { Ok(match bits_per_entry { 0 => Palette::SingleValue(u32::read_into(buf)?), - 1..=4 => Palette::LinearPalette(Vec::::read_into(buf)?), - 5..=8 => Palette::HashmapPalette(Vec::::read_into(buf)?), - _ => Palette::GlobalPalette, + 1..=4 => Palette::Linear(Vec::::read_into(buf)?), + 5..=8 => Palette::Hashmap(Vec::::read_into(buf)?), + _ => Palette::Global, }) } } @@ -60,13 +60,13 @@ impl McBufWritable for Palette { Palette::SingleValue(value) => { value.write_into(buf)?; } - Palette::LinearPalette(values) => { + Palette::Linear(values) => { values.write_into(buf)?; } - Palette::HashmapPalette(values) => { + Palette::Hashmap(values) => { values.write_into(buf)?; } - Palette::GlobalPalette => {} + Palette::Global => {} } Ok(()) } From 18dc3a84d4b58a58085682cc97f1b52ffee5091c Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 22:48:57 -0500 Subject: [PATCH 08/29] start adding bit storage --- .gitignore | 3 + azalea-world/src/bit_storage.rs | 149 ++++++++++++++++++++++++++++++++ azalea-world/src/lib.rs | 2 + bot/src/main.rs | 2 +- 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 azalea-world/src/bit_storage.rs diff --git a/.gitignore b/.gitignore index ad9bfc78..364ea72c 100755 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ flamegraph.svg perf.data perf.data.old + +# TODO: remove this after chunk-decoding is merged +/login.txt diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs new file mode 100644 index 00000000..b2202e48 --- /dev/null +++ b/azalea-world/src/bit_storage.rs @@ -0,0 +1,149 @@ +use std::{error::Error, fmt}; + +// this is from minecraft's code +// yeah idk either +const MAGIC: [(i32, i32, i32); 64] = [ + (-1, -1, 0), + (-2147483648, 0, 0), + (1431655765, 1431655765, 0), + (-2147483648, 0, 1), + (858993459, 858993459, 0), + (715827882, 715827882, 0), + (613566756, 613566756, 0), + (-2147483648, 0, 2), + (477218588, 477218588, 0), + (429496729, 429496729, 0), + (390451572, 390451572, 0), + (357913941, 357913941, 0), + (330382099, 330382099, 0), + (306783378, 306783378, 0), + (286331153, 286331153, 0), + (-2147483648, 0, 3), + (252645135, 252645135, 0), + (238609294, 238609294, 0), + (226050910, 226050910, 0), + (214748364, 214748364, 0), + (204522252, 204522252, 0), + (195225786, 195225786, 0), + (186737708, 186737708, 0), + (178956970, 178956970, 0), + (171798691, 171798691, 0), + (165191049, 165191049, 0), + (159072862, 159072862, 0), + (153391689, 153391689, 0), + (148102320, 148102320, 0), + (143165576, 143165576, 0), + (138547332, 138547332, 0), + (-2147483648, 0, 4), + (130150524, 130150524, 0), + (126322567, 126322567, 0), + (122713351, 122713351, 0), + (119304647, 119304647, 0), + (116080197, 116080197, 0), + (113025455, 113025455, 0), + (110127366, 110127366, 0), + (107374182, 107374182, 0), + (104755299, 104755299, 0), + (102261126, 102261126, 0), + (99882960, 99882960, 0), + (97612893, 97612893, 0), + (95443717, 95443717, 0), + (93368854, 93368854, 0), + (91382282, 91382282, 0), + (89478485, 89478485, 0), + (87652393, 87652393, 0), + (85899345, 85899345, 0), + (84215045, 84215045, 0), + (82595524, 82595524, 0), + (81037118, 81037118, 0), + (79536431, 79536431, 0), + (78090314, 78090314, 0), + (76695844, 76695844, 0), + (75350303, 75350303, 0), + (74051160, 74051160, 0), + (72796055, 72796055, 0), + (71582788, 71582788, 0), + (70409299, 70409299, 0), + (69273666, 69273666, 0), + (68174084, 68174084, 0), + (-2147483648, 0, 5), +]; + +/// A compact list of integers with the given number of bits per entry. +pub struct BitStorage { + data: Vec, + bits: u32, + mask: u64, + size: u32, + values_per_long: u8, + divide_mul: i32, + divide_add: i32, + divide_shift: i32, +} + +#[derive(Debug)] +pub enum BitStorageError { + InvalidLength { got: usize, expected: usize }, +} +impl fmt::Display for BitStorageError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + BitStorageError::InvalidLength { got, expected } => write!( + f, + "Invalid length given for storage, got: {}, but expected: {}", + got, expected + ), + } + } +} +impl Error for BitStorageError {} + +impl BitStorage { + /// Create a new BitStorage with the given number of bits per entry. + /// `size` is the number of entries in the BitStorage. + pub fn new(bits: u32, size: u32, data: Option>) -> Result { + let values_per_long = 64 / bits; + let magic_index = values_per_long - 1; + let (divide_mul, divide_add, divide_shift) = MAGIC[magic_index as usize]; + let calculated_length = (size + values_per_long - 1) / values_per_long; + + let mask = (1 << bits) - 1; + + let using_data = if let Some(data) = data { + if data.len() != calculated_length as usize { + return Err(BitStorageError::InvalidLength { + got: data.len(), + expected: calculated_length as usize, + }); + } + data + } else { + vec![0; calculated_length as usize] + }; + + Ok(BitStorage { + data: using_data, + bits, + mask, + size, + values_per_long: values_per_long as u8, + divide_mul, + divide_add, + divide_shift, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_wikivg_example() { + let data = [ + 1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2, + ]; + let expected_compact: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87]; + let storage = BitStorage::new(5, 10, None).unwrap(); + } +} diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index ea7798f8..54961401 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,7 +1,9 @@ +mod bit_storage; mod palette; use azalea_core::ChunkPos; use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; +pub use bit_storage::BitStorage; use palette::PalettedContainer; use std::{ io::{Read, Write}, diff --git a/bot/src/main.rs b/bot/src/main.rs index 6a2d5959..504c8d41 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -5,7 +5,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "172.23.192.1:59152"; + let address = "172.23.192.1:65163"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); From 9a9fd8fcdda6e36a2468731034df9c13f45e378f Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 22:49:11 -0500 Subject: [PATCH 09/29] Delete login.txt --- login.txt | 4245 ----------------------------------------------------- 1 file changed, 4245 deletions(-) delete mode 100644 login.txt diff --git a/login.txt b/login.txt deleted file mode 100644 index 15e011e3..00000000 --- a/login.txt +++ /dev/null @@ -1,4245 +0,0 @@ -ClientboundLoginPacket { - player_id: 26888, - hardcore: false, - game_type: CREATIVE, - previous_game_type: None, - levels: [ - minecraft:overworld, - minecraft:the_end, - minecraft:the_nether, - ], - registry_holder: Compound( - { - "": Compound( - { - "minecraft:worldgen/biome": Compound( - { - "type": String( - "minecraft:worldgen/biome", - ), - "value": List( - [ - Compound( - { - "element": Compound( - { - "precipitation": String( - "none", - ), - "temperature": Float( - 0.5, - ), - "category": String( - "none", - ), - "effects": Compound( - { - "sky_color": Int( - 8103167, - ), - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "downfall": Float( - 0.5, - ), - }, - ), - "name": String( - "minecraft:the_void", - ), - "id": Int( - 0, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:plains", - ), - "id": Int( - 1, - ), - "element": Compound( - { - "category": String( - "plains", - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7907327, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.8, - ), - "downfall": Float( - 0.4, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:sunflower_plains", - ), - "id": Int( - 2, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.4, - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - }, - ), - "sky_color": Int( - 7907327, - ), - }, - ), - "category": String( - "plains", - ), - "temperature": Float( - 0.8, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:snowy_plains", - ), - "element": Compound( - { - "category": String( - "icy", - ), - "temperature": Float( - 0.0, - ), - "precipitation": String( - "snow", - ), - "downfall": Float( - 0.5, - ), - "effects": Compound( - { - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8364543, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - }, - ), - "id": Int( - 3, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:ice_spikes", - ), - "element": Compound( - { - "precipitation": String( - "snow", - ), - "temperature": Float( - 0.0, - ), - "category": String( - "icy", - ), - "downfall": Float( - 0.5, - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 8364543, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - }, - ), - }, - ), - "id": Int( - 4, - ), - }, - ), - Compound( - { - "id": Int( - 5, - ), - "name": String( - "minecraft:desert", - ), - "element": Compound( - { - "category": String( - "desert", - ), - "temperature": Float( - 2.0, - ), - "downfall": Float( - 0.0, - ), - "precipitation": String( - "none", - ), - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "category": String( - "swamp", - ), - "effects": Compound( - { - "water_color": Int( - 6388580, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7907327, - ), - "grass_color_modifier": String( - "swamp", - ), - "foliage_color": Int( - 6975545, - ), - "water_fog_color": Int( - 2302743, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.8, - ), - "downfall": Float( - 0.9, - ), - }, - ), - "id": Int( - 6, - ), - "name": String( - "minecraft:swamp", - ), - }, - ), - Compound( - { - "id": Int( - 7, - ), - "element": Compound( - { - "temperature": Float( - 0.7, - ), - "category": String( - "forest", - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.8, - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 7972607, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - }, - ), - "name": String( - "minecraft:forest", - ), - }, - ), - Compound( - { - "id": Int( - 8, - ), - "element": Compound( - { - "effects": Compound( - { - "sky_color": Int( - 7972607, - ), - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "precipitation": String( - "rain", - ), - "category": String( - "forest", - ), - "temperature": Float( - 0.7, - ), - "downfall": Float( - 0.8, - ), - }, - ), - "name": String( - "minecraft:flower_forest", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:birch_forest", - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "sky_color": Int( - 8037887, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - "downfall": Float( - 0.6, - ), - "temperature": Float( - 0.6, - ), - "category": String( - "forest", - ), - }, - ), - "id": Int( - 9, - ), - }, - ), - Compound( - { - "id": Int( - 10, - ), - "element": Compound( - { - "downfall": Float( - 0.8, - ), - "precipitation": String( - "rain", - ), - "category": String( - "forest", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "grass_color_modifier": String( - "dark_forest", - ), - "sky_color": Int( - 7972607, - ), - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - }, - ), - "temperature": Float( - 0.7, - ), - }, - ), - "name": String( - "minecraft:dark_forest", - ), - }, - ), - Compound( - { - "id": Int( - 11, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.6, - ), - "temperature": Float( - 0.6, - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8037887, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "category": String( - "forest", - ), - }, - ), - "name": String( - "minecraft:old_growth_birch_forest", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:old_growth_pine_taiga", - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "category": String( - "taiga", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8168447, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - "temperature": Float( - 0.3, - ), - "downfall": Float( - 0.8, - ), - }, - ), - "id": Int( - 12, - ), - }, - ), - Compound( - { - "id": Int( - 13, - ), - "name": String( - "minecraft:old_growth_spruce_taiga", - ), - "element": Compound( - { - "category": String( - "taiga", - ), - "downfall": Float( - 0.8, - ), - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "sky_color": Int( - 8233983, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "temperature": Float( - 0.25, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:taiga", - ), - "id": Int( - 14, - ), - "element": Compound( - { - "temperature": Float( - 0.25, - ), - "downfall": Float( - 0.8, - ), - "precipitation": String( - "rain", - ), - "category": String( - "taiga", - ), - "effects": Compound( - { - "sky_color": Int( - 8233983, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 15, - ), - "element": Compound( - { - "downfall": Float( - 0.4, - ), - "temperature": Float( - -0.5, - ), - "effects": Compound( - { - "water_color": Int( - 4020182, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8625919, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "category": String( - "taiga", - ), - "precipitation": String( - "snow", - ), - }, - ), - "name": String( - "minecraft:snowy_taiga", - ), - }, - ), - Compound( - { - "element": Compound( - { - "temperature": Float( - 2.0, - ), - "downfall": Float( - 0.0, - ), - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - }, - ), - }, - ), - "precipitation": String( - "none", - ), - "category": String( - "savanna", - ), - }, - ), - "name": String( - "minecraft:savanna", - ), - "id": Int( - 16, - ), - }, - ), - Compound( - { - "id": Int( - 17, - ), - "name": String( - "minecraft:savanna_plateau", - ), - "element": Compound( - { - "downfall": Float( - 0.0, - ), - "category": String( - "savanna", - ), - "precipitation": String( - "none", - ), - "temperature": Float( - 2.0, - ), - "effects": Compound( - { - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 7254527, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 18, - ), - "name": String( - "minecraft:windswept_hills", - ), - "element": Compound( - { - "temperature": Float( - 0.2, - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.3, - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8233727, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - }, - ), - "category": String( - "extreme_hills", - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 19, - ), - "element": Compound( - { - "temperature": Float( - 0.2, - ), - "precipitation": String( - "rain", - ), - "category": String( - "extreme_hills", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 8233727, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - }, - ), - "downfall": Float( - 0.3, - ), - }, - ), - "name": String( - "minecraft:windswept_gravelly_hills", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:windswept_forest", - ), - "id": Int( - 20, - ), - "element": Compound( - { - "category": String( - "extreme_hills", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 8233727, - ), - }, - ), - "downfall": Float( - 0.3, - ), - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.2, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:windswept_savanna", - ), - "element": Compound( - { - "temperature": Float( - 2.0, - ), - "downfall": Float( - 0.0, - ), - "category": String( - "savanna", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "sky_color": Int( - 7254527, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - "precipitation": String( - "none", - ), - }, - ), - "id": Int( - 21, - ), - }, - ), - Compound( - { - "id": Int( - 22, - ), - "name": String( - "minecraft:jungle", - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.95, - ), - "downfall": Float( - 0.9, - ), - "category": String( - "jungle", - ), - "effects": Compound( - { - "sky_color": Int( - 7842047, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "temperature": Float( - 0.95, - ), - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7842047, - ), - }, - ), - "category": String( - "jungle", - ), - "downfall": Float( - 0.8, - ), - }, - ), - "id": Int( - 23, - ), - "name": String( - "minecraft:sparse_jungle", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:bamboo_jungle", - ), - "id": Int( - 24, - ), - "element": Compound( - { - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7842047, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "downfall": Float( - 0.9, - ), - "temperature": Float( - 0.95, - ), - "precipitation": String( - "rain", - ), - "category": String( - "jungle", - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:badlands", - ), - "id": Int( - 25, - ), - "element": Compound( - { - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "foliage_color": Int( - 10387789, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "grass_color": Int( - 9470285, - ), - }, - ), - "category": String( - "mesa", - ), - "precipitation": String( - "none", - ), - "downfall": Float( - 0.0, - ), - "temperature": Float( - 2.0, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:eroded_badlands", - ), - "id": Int( - 26, - ), - "element": Compound( - { - "downfall": Float( - 0.0, - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "grass_color": Int( - 9470285, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "foliage_color": Int( - 10387789, - ), - "sky_color": Int( - 7254527, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "precipitation": String( - "none", - ), - "category": String( - "mesa", - ), - "temperature": Float( - 2.0, - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "foliage_color": Int( - 10387789, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - }, - ), - "grass_color": Int( - 9470285, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "temperature": Float( - 2.0, - ), - "downfall": Float( - 0.0, - ), - "category": String( - "mesa", - ), - "precipitation": String( - "none", - ), - }, - ), - "name": String( - "minecraft:wooded_badlands", - ), - "id": Int( - 27, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:meadow", - ), - "id": Int( - 28, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.5, - ), - "effects": Compound( - { - "sky_color": Int( - 8103167, - ), - "water_color": Int( - 937679, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.meadow", - ), - "replace_current_music": Byte( - 0, - ), - "max_delay": Int( - 24000, - ), - "min_delay": Int( - 12000, - ), - }, - ), - }, - ), - "category": String( - "mountain", - ), - "downfall": Float( - 0.8, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:grove", - ), - "id": Int( - 29, - ), - "element": Compound( - { - "precipitation": String( - "snow", - ), - "effects": Compound( - { - "music": Compound( - { - "min_delay": Int( - 12000, - ), - "max_delay": Int( - 24000, - ), - "replace_current_music": Byte( - 0, - ), - "sound": String( - "minecraft:music.overworld.grove", - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "sky_color": Int( - 8495359, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "temperature": Float( - -0.2, - ), - "downfall": Float( - 0.8, - ), - "category": String( - "forest", - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "temperature": Float( - -0.3, - ), - "precipitation": String( - "snow", - ), - "category": String( - "mountain", - ), - "effects": Compound( - { - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.snowy_slopes", - ), - "min_delay": Int( - 12000, - ), - "max_delay": Int( - 24000, - ), - "replace_current_music": Byte( - 0, - ), - }, - ), - "sky_color": Int( - 8560639, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "water_color": Int( - 4159204, - ), - }, - ), - "downfall": Float( - 0.9, - ), - }, - ), - "name": String( - "minecraft:snowy_slopes", - ), - "id": Int( - 30, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:frozen_peaks", - ), - "id": Int( - 31, - ), - "element": Compound( - { - "category": String( - "mountain", - ), - "precipitation": String( - "snow", - ), - "downfall": Float( - 0.9, - ), - "temperature": Float( - -0.7, - ), - "effects": Compound( - { - "sky_color": Int( - 8756735, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.frozen_peaks", - ), - "min_delay": Int( - 12000, - ), - "replace_current_music": Byte( - 0, - ), - "max_delay": Int( - 24000, - ), - }, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:jagged_peaks", - ), - "id": Int( - 32, - ), - "element": Compound( - { - "precipitation": String( - "snow", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "music": Compound( - { - "replace_current_music": Byte( - 0, - ), - "max_delay": Int( - 24000, - ), - "sound": String( - "minecraft:music.overworld.jagged_peaks", - ), - "min_delay": Int( - 12000, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 8756735, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "temperature": Float( - -0.7, - ), - "downfall": Float( - 0.9, - ), - "category": String( - "mountain", - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 33, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.3, - ), - "temperature": Float( - 1.0, - ), - "category": String( - "mountain", - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.stony_peaks", - ), - "replace_current_music": Byte( - 0, - ), - "max_delay": Int( - 24000, - ), - "min_delay": Int( - 12000, - ), - }, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7776511, - ), - "water_color": Int( - 4159204, - ), - }, - ), - }, - ), - "name": String( - "minecraft:stony_peaks", - ), - }, - ), - Compound( - { - "id": Int( - 34, - ), - "element": Compound( - { - "temperature": Float( - 0.5, - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8103167, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - }, - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.5, - ), - "category": String( - "river", - ), - }, - ), - "name": String( - "minecraft:river", - ), - }, - ), - Compound( - { - "element": Compound( - { - "category": String( - "river", - ), - "precipitation": String( - "snow", - ), - "effects": Compound( - { - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "sky_color": Int( - 8364543, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 3750089, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "temperature": Float( - 0.0, - ), - "downfall": Float( - 0.5, - ), - }, - ), - "name": String( - "minecraft:frozen_river", - ), - "id": Int( - 35, - ), - }, - ), - Compound( - { - "id": Int( - 36, - ), - "name": String( - "minecraft:beach", - ), - "element": Compound( - { - "temperature": Float( - 0.8, - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.4, - ), - "category": String( - "beach", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 7907327, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "downfall": Float( - 0.3, - ), - "category": String( - "beach", - ), - "precipitation": String( - "snow", - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8364543, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4020182, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - }, - ), - "temperature": Float( - 0.05, - ), - }, - ), - "id": Int( - 37, - ), - "name": String( - "minecraft:snowy_beach", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:stony_shore", - ), - "element": Compound( - { - "temperature": Float( - 0.2, - ), - "category": String( - "beach", - ), - "downfall": Float( - 0.3, - ), - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "sky_color": Int( - 8233727, - ), - }, - ), - }, - ), - "id": Int( - 38, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:warm_ocean", - ), - "id": Int( - 39, - ), - "element": Compound( - { - "downfall": Float( - 0.5, - ), - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.5, - ), - "category": String( - "ocean", - ), - "effects": Compound( - { - "sky_color": Int( - 8103167, - ), - "water_color": Int( - 4445678, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - "water_fog_color": Int( - 270131, - ), - "fog_color": Int( - 12638463, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:lukewarm_ocean", - ), - "element": Compound( - { - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4566514, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 8103167, - ), - "water_fog_color": Int( - 267827, - ), - }, - ), - "temperature": Float( - 0.5, - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.5, - ), - "category": String( - "ocean", - ), - }, - ), - "id": Int( - 40, - ), - }, - ), - Compound( - { - "id": Int( - 41, - ), - "element": Compound( - { - "temperature": Float( - 0.5, - ), - "downfall": Float( - 0.5, - ), - "effects": Compound( - { - "sky_color": Int( - 8103167, - ), - "water_fog_color": Int( - 267827, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_color": Int( - 4566514, - ), - }, - ), - "precipitation": String( - "rain", - ), - "category": String( - "ocean", - ), - }, - ), - "name": String( - "minecraft:deep_lukewarm_ocean", - ), - }, - ), - Compound( - { - "element": Compound( - { - "category": String( - "ocean", - ), - "temperature": Float( - 0.5, - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8103167, - ), - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - }, - ), - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.5, - ), - }, - ), - "id": Int( - 42, - ), - "name": String( - "minecraft:ocean", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:deep_ocean", - ), - "id": Int( - 43, - ), - "element": Compound( - { - "downfall": Float( - 0.5, - ), - "effects": Compound( - { - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8103167, - ), - }, - ), - "category": String( - "ocean", - ), - "temperature": Float( - 0.5, - ), - "precipitation": String( - "rain", - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:cold_ocean", - ), - "element": Compound( - { - "temperature": Float( - 0.5, - ), - "downfall": Float( - 0.5, - ), - "precipitation": String( - "rain", - ), - "category": String( - "ocean", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8103167, - ), - "water_color": Int( - 4020182, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - }, - ), - }, - ), - "id": Int( - 44, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:deep_cold_ocean", - ), - "id": Int( - 45, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "downfall": Float( - 0.5, - ), - "temperature": Float( - 0.5, - ), - "category": String( - "ocean", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 8103167, - ), - "water_color": Int( - 4020182, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:frozen_ocean", - ), - "element": Compound( - { - "effects": Compound( - { - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "sky_color": Int( - 8364543, - ), - "water_color": Int( - 3750089, - ), - }, - ), - "precipitation": String( - "snow", - ), - "temperature": Float( - 0.0, - ), - "downfall": Float( - 0.5, - ), - "temperature_modifier": String( - "frozen", - ), - "category": String( - "ocean", - ), - }, - ), - "id": Int( - 46, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:deep_frozen_ocean", - ), - "id": Int( - 47, - ), - "element": Compound( - { - "temperature_modifier": String( - "frozen", - ), - "temperature": Float( - 0.5, - ), - "downfall": Float( - 0.5, - ), - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 12638463, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_color": Int( - 3750089, - ), - "sky_color": Int( - 8103167, - ), - }, - ), - "category": String( - "ocean", - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 48, - ), - "name": String( - "minecraft:mushroom_fields", - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 7842047, - ), - "fog_color": Int( - 12638463, - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "downfall": Float( - 1.0, - ), - "temperature": Float( - 0.9, - ), - "category": String( - "mushroom", - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:dripstone_caves", - ), - "id": Int( - 49, - ), - "element": Compound( - { - "precipitation": String( - "rain", - ), - "temperature": Float( - 0.8, - ), - "downfall": Float( - 0.4, - ), - "category": String( - "underground", - ), - "effects": Compound( - { - "sky_color": Int( - 7907327, - ), - "water_fog_color": Int( - 329011, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.dripstone_caves", - ), - "max_delay": Int( - 24000, - ), - "min_delay": Int( - 12000, - ), - "replace_current_music": Byte( - 0, - ), - }, - ), - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - }, - ), - }, - ), - }, - ), - Compound( - { - "element": Compound( - { - "downfall": Float( - 0.5, - ), - "temperature": Float( - 0.5, - ), - "category": String( - "underground", - ), - "effects": Compound( - { - "fog_color": Int( - 12638463, - ), - "water_color": Int( - 4159204, - ), - "sky_color": Int( - 8103167, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.overworld.lush_caves", - ), - "min_delay": Int( - 12000, - ), - "max_delay": Int( - 24000, - ), - "replace_current_music": Byte( - 0, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - }, - ), - }, - ), - "precipitation": String( - "rain", - ), - }, - ), - "id": Int( - 50, - ), - "name": String( - "minecraft:lush_caves", - ), - }, - ), - Compound( - { - "element": Compound( - { - "effects": Compound( - { - "music": Compound( - { - "max_delay": Int( - 24000, - ), - "sound": String( - "minecraft:music.nether.nether_wastes", - ), - "min_delay": Int( - 12000, - ), - "replace_current_music": Byte( - 0, - ), - }, - ), - "fog_color": Int( - 3344392, - ), - "sky_color": Int( - 7254527, - ), - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - "ambient_sound": String( - "minecraft:ambient.nether_wastes.loop", - ), - "additions_sound": Compound( - { - "sound": String( - "minecraft:ambient.nether_wastes.additions", - ), - "tick_chance": Double( - 0.0111, - ), - }, - ), - "mood_sound": Compound( - { - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.nether_wastes.mood", - ), - }, - ), - }, - ), - "temperature": Float( - 2.0, - ), - "precipitation": String( - "none", - ), - "category": String( - "nether", - ), - "downfall": Float( - 0.0, - ), - }, - ), - "id": Int( - 51, - ), - "name": String( - "minecraft:nether_wastes", - ), - }, - ), - Compound( - { - "element": Compound( - { - "downfall": Float( - 0.0, - ), - "category": String( - "nether", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 7254527, - ), - "fog_color": Int( - 1705242, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.warped_forest.mood", - ), - "block_search_extent": Int( - 8, - ), - "offset": Double( - 2.0, - ), - }, - ), - "music": Compound( - { - "sound": String( - "minecraft:music.nether.warped_forest", - ), - "replace_current_music": Byte( - 0, - ), - "min_delay": Int( - 12000, - ), - "max_delay": Int( - 24000, - ), - }, - ), - "water_color": Int( - 4159204, - ), - "additions_sound": Compound( - { - "sound": String( - "minecraft:ambient.warped_forest.additions", - ), - "tick_chance": Double( - 0.0111, - ), - }, - ), - "ambient_sound": String( - "minecraft:ambient.warped_forest.loop", - ), - "particle": Compound( - { - "options": Compound( - { - "type": String( - "minecraft:warped_spore", - ), - }, - ), - "probability": Float( - 0.01428, - ), - }, - ), - }, - ), - "temperature": Float( - 2.0, - ), - "precipitation": String( - "none", - ), - }, - ), - "id": Int( - 52, - ), - "name": String( - "minecraft:warped_forest", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:crimson_forest", - ), - "id": Int( - 53, - ), - "element": Compound( - { - "precipitation": String( - "none", - ), - "downfall": Float( - 0.0, - ), - "temperature": Float( - 2.0, - ), - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "water_color": Int( - 4159204, - ), - "particle": Compound( - { - "probability": Float( - 0.025, - ), - "options": Compound( - { - "type": String( - "minecraft:crimson_spore", - ), - }, - ), - }, - ), - "ambient_sound": String( - "minecraft:ambient.crimson_forest.loop", - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.crimson_forest.mood", - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "additions_sound": Compound( - { - "tick_chance": Double( - 0.0111, - ), - "sound": String( - "minecraft:ambient.crimson_forest.additions", - ), - }, - ), - "fog_color": Int( - 3343107, - ), - "music": Compound( - { - "max_delay": Int( - 24000, - ), - "sound": String( - "minecraft:music.nether.crimson_forest", - ), - "replace_current_music": Byte( - 0, - ), - "min_delay": Int( - 12000, - ), - }, - ), - }, - ), - "category": String( - "nether", - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:soul_sand_valley", - ), - "id": Int( - 54, - ), - "element": Compound( - { - "category": String( - "nether", - ), - "effects": Compound( - { - "sky_color": Int( - 7254527, - ), - "additions_sound": Compound( - { - "tick_chance": Double( - 0.0111, - ), - "sound": String( - "minecraft:ambient.soul_sand_valley.additions", - ), - }, - ), - "particle": Compound( - { - "options": Compound( - { - "type": String( - "minecraft:ash", - ), - }, - ), - "probability": Float( - 0.00625, - ), - }, - ), - "water_color": Int( - 4159204, - ), - "music": Compound( - { - "min_delay": Int( - 12000, - ), - "replace_current_music": Byte( - 0, - ), - "max_delay": Int( - 24000, - ), - "sound": String( - "minecraft:music.nether.soul_sand_valley", - ), - }, - ), - "fog_color": Int( - 1787717, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.soul_sand_valley.mood", - ), - }, - ), - "ambient_sound": String( - "minecraft:ambient.soul_sand_valley.loop", - ), - "water_fog_color": Int( - 329011, - ), - }, - ), - "precipitation": String( - "none", - ), - "downfall": Float( - 0.0, - ), - "temperature": Float( - 2.0, - ), - }, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:basalt_deltas", - ), - "element": Compound( - { - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "music": Compound( - { - "replace_current_music": Byte( - 0, - ), - "min_delay": Int( - 12000, - ), - "sound": String( - "minecraft:music.nether.basalt_deltas", - ), - "max_delay": Int( - 24000, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "particle": Compound( - { - "probability": Float( - 0.118093334, - ), - "options": Compound( - { - "type": String( - "minecraft:white_ash", - ), - }, - ), - }, - ), - "sky_color": Int( - 7254527, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.basalt_deltas.mood", - ), - }, - ), - "ambient_sound": String( - "minecraft:ambient.basalt_deltas.loop", - ), - "additions_sound": Compound( - { - "tick_chance": Double( - 0.0111, - ), - "sound": String( - "minecraft:ambient.basalt_deltas.additions", - ), - }, - ), - "fog_color": Int( - 6840176, - ), - }, - ), - "temperature": Float( - 2.0, - ), - "downfall": Float( - 0.0, - ), - "category": String( - "nether", - ), - "precipitation": String( - "none", - ), - }, - ), - "id": Int( - 55, - ), - }, - ), - Compound( - { - "id": Int( - 56, - ), - "element": Compound( - { - "precipitation": String( - "none", - ), - "temperature": Float( - 0.5, - ), - "effects": Compound( - { - "sky_color": Int( - 0, - ), - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "fog_color": Int( - 10518688, - ), - }, - ), - "category": String( - "the_end", - ), - "downfall": Float( - 0.5, - ), - }, - ), - "name": String( - "minecraft:the_end", - ), - }, - ), - Compound( - { - "element": Compound( - { - "temperature": Float( - 0.5, - ), - "downfall": Float( - 0.5, - ), - "precipitation": String( - "none", - ), - "category": String( - "the_end", - ), - "effects": Compound( - { - "water_fog_color": Int( - 329011, - ), - "water_color": Int( - 4159204, - ), - "fog_color": Int( - 10518688, - ), - "mood_sound": Compound( - { - "block_search_extent": Int( - 8, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - }, - ), - "sky_color": Int( - 0, - ), - }, - ), - }, - ), - "id": Int( - 57, - ), - "name": String( - "minecraft:end_highlands", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:end_midlands", - ), - "id": Int( - 58, - ), - "element": Compound( - { - "temperature": Float( - 0.5, - ), - "effects": Compound( - { - "fog_color": Int( - 10518688, - ), - "water_color": Int( - 4159204, - ), - "water_fog_color": Int( - 329011, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 0, - ), - }, - ), - "category": String( - "the_end", - ), - "precipitation": String( - "none", - ), - "downfall": Float( - 0.5, - ), - }, - ), - }, - ), - Compound( - { - "id": Int( - 59, - ), - "element": Compound( - { - "category": String( - "the_end", - ), - "precipitation": String( - "none", - ), - "downfall": Float( - 0.5, - ), - "effects": Compound( - { - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "sound": String( - "minecraft:ambient.cave", - ), - "offset": Double( - 2.0, - ), - "tick_delay": Int( - 6000, - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "sky_color": Int( - 0, - ), - "water_fog_color": Int( - 329011, - ), - "fog_color": Int( - 10518688, - ), - }, - ), - "temperature": Float( - 0.5, - ), - }, - ), - "name": String( - "minecraft:small_end_islands", - ), - }, - ), - Compound( - { - "name": String( - "minecraft:end_barrens", - ), - "id": Int( - 60, - ), - "element": Compound( - { - "precipitation": String( - "none", - ), - "effects": Compound( - { - "fog_color": Int( - 10518688, - ), - "water_color": Int( - 4159204, - ), - "mood_sound": Compound( - { - "tick_delay": Int( - 6000, - ), - "offset": Double( - 2.0, - ), - "sound": String( - "minecraft:ambient.cave", - ), - "block_search_extent": Int( - 8, - ), - }, - ), - "water_fog_color": Int( - 329011, - ), - "sky_color": Int( - 0, - ), - }, - ), - "downfall": Float( - 0.5, - ), - "temperature": Float( - 0.5, - ), - "category": String( - "the_end", - ), - }, - ), - }, - ), - ], - ), - }, - ), - "minecraft:dimension_type": Compound( - { - "type": String( - "minecraft:dimension_type", - ), - "value": List( - [ - Compound( - { - "name": String( - "minecraft:overworld", - ), - "element": Compound( - { - "ambient_light": Float( - 0.0, - ), - "effects": String( - "minecraft:overworld", - ), - "min_y": Int( - -64, - ), - "bed_works": Byte( - 1, - ), - "has_raids": Byte( - 1, - ), - "height": Int( - 384, - ), - "natural": Byte( - 1, - ), - "has_ceiling": Byte( - 0, - ), - "has_skylight": Byte( - 1, - ), - "respawn_anchor_works": Byte( - 0, - ), - "coordinate_scale": Double( - 1.0, - ), - "ultrawarm": Byte( - 0, - ), - "piglin_safe": Byte( - 0, - ), - "infiniburn": String( - "#minecraft:infiniburn_overworld", - ), - "logical_height": Int( - 384, - ), - }, - ), - "id": Int( - 0, - ), - }, - ), - Compound( - { - "name": String( - "minecraft:overworld_caves", - ), - "element": Compound( - { - "piglin_safe": Byte( - 0, - ), - "has_ceiling": Byte( - 1, - ), - "has_raids": Byte( - 1, - ), - "effects": String( - "minecraft:overworld", - ), - "infiniburn": String( - "#minecraft:infiniburn_overworld", - ), - "min_y": Int( - -64, - ), - "has_skylight": Byte( - 1, - ), - "ultrawarm": Byte( - 0, - ), - "logical_height": Int( - 384, - ), - "coordinate_scale": Double( - 1.0, - ), - "ambient_light": Float( - 0.0, - ), - "respawn_anchor_works": Byte( - 0, - ), - "bed_works": Byte( - 1, - ), - "height": Int( - 384, - ), - "natural": Byte( - 1, - ), - }, - ), - "id": Int( - 1, - ), - }, - ), - Compound( - { - "id": Int( - 2, - ), - "element": Compound( - { - "respawn_anchor_works": Byte( - 1, - ), - "infiniburn": String( - "#minecraft:infiniburn_nether", - ), - "ambient_light": Float( - 0.1, - ), - "has_skylight": Byte( - 0, - ), - "fixed_time": Long( - 18000, - ), - "bed_works": Byte( - 0, - ), - "effects": String( - "minecraft:the_nether", - ), - "coordinate_scale": Double( - 8.0, - ), - "logical_height": Int( - 128, - ), - "has_raids": Byte( - 0, - ), - "height": Int( - 256, - ), - "min_y": Int( - 0, - ), - "natural": Byte( - 0, - ), - "has_ceiling": Byte( - 1, - ), - "piglin_safe": Byte( - 1, - ), - "ultrawarm": Byte( - 1, - ), - }, - ), - "name": String( - "minecraft:the_nether", - ), - }, - ), - Compound( - { - "id": Int( - 3, - ), - "name": String( - "minecraft:the_end", - ), - "element": Compound( - { - "height": Int( - 256, - ), - "logical_height": Int( - 256, - ), - "ambient_light": Float( - 0.0, - ), - "natural": Byte( - 0, - ), - "has_ceiling": Byte( - 0, - ), - "respawn_anchor_works": Byte( - 0, - ), - "min_y": Int( - 0, - ), - "piglin_safe": Byte( - 0, - ), - "has_skylight": Byte( - 0, - ), - "bed_works": Byte( - 0, - ), - "infiniburn": String( - "#minecraft:infiniburn_end", - ), - "effects": String( - "minecraft:the_end", - ), - "fixed_time": Long( - 6000, - ), - "has_raids": Byte( - 1, - ), - "coordinate_scale": Double( - 1.0, - ), - "ultrawarm": Byte( - 0, - ), - }, - ), - }, - ), - ], - ), - }, - ), - }, - ), - }, - ), - dimension_type: Compound( - { - "": Compound( - { - "coordinate_scale": Double( - 1.0, - ), - "ambient_light": Float( - 0.0, - ), - "effects": String( - "minecraft:overworld", - ), - "min_y": Int( - -64, - ), - "ultrawarm": Byte( - 0, - ), - "has_skylight": Byte( - 1, - ), - "bed_works": Byte( - 1, - ), - "logical_height": Int( - 384, - ), - "natural": Byte( - 1, - ), - "has_raids": Byte( - 1, - ), - "piglin_safe": Byte( - 0, - ), - "respawn_anchor_works": Byte( - 0, - ), - "has_ceiling": Byte( - 0, - ), - "infiniburn": String( - "#minecraft:infiniburn_overworld", - ), - "height": Int( - 384, - ), - }, - ), - }, - ), - dimension: minecraft:overworld, - seed: -8740116197493662413, - max_players: 8, - chunk_radius: 8, - simulation_distance: 5, - reduced_debug_info: false, - show_death_screen: true, - is_debug: false, - is_flat: false, -} \ No newline at end of file From 57b76ef52b7a9b516710aea5ba5d6f0141c8d6cf Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 5 May 2022 19:57:46 -0500 Subject: [PATCH 10/29] Add bit storage --- azalea-world/src/bit_storage.rs | 53 +++++++++++++++++++++++++++++---- bot/src/main.rs | 2 +- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index b2202e48..5ced67fe 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fmt}; +use std::{error::Error, fmt, ops::Index}; // this is from minecraft's code // yeah idk either @@ -72,9 +72,9 @@ const MAGIC: [(i32, i32, i32); 64] = [ /// A compact list of integers with the given number of bits per entry. pub struct BitStorage { data: Vec, - bits: u32, + bits: usize, mask: u64, - size: u32, + size: usize, values_per_long: u8, divide_mul: i32, divide_add: i32, @@ -101,7 +101,7 @@ impl Error for BitStorageError {} impl BitStorage { /// Create a new BitStorage with the given number of bits per entry. /// `size` is the number of entries in the BitStorage. - pub fn new(bits: u32, size: u32, data: Option>) -> Result { + pub fn new(bits: usize, size: usize, data: Option>) -> Result { let values_per_long = 64 / bits; let magic_index = values_per_long - 1; let (divide_mul, divide_add, divide_shift) = MAGIC[magic_index as usize]; @@ -132,6 +132,45 @@ impl BitStorage { divide_shift, }) } + + pub fn cell_index(&self, index: u64) -> usize { + let first = self.divide_mul as u64; + let second = self.divide_mul as u64; + + (index * first + second >> 32 >> self.divide_shift) + .try_into() + .unwrap() + } + + pub fn get(&self, index: usize) -> u64 { + // Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)var1); + // int var2 = this.cellIndex(var1); + // long var3 = this.data[var2]; + // int var5 = (var1 - var2 * this.valuesPerLong) * this.bits; + // return (int)(var3 >> var5 & this.mask); + + assert!(index <= self.size - 1); + let cell_index = self.cell_index(index as u64); + let cell = &self.data[cell_index as usize]; + let bit_index = (index - cell_index * self.values_per_long as usize) * self.bits; + cell >> bit_index & self.mask + } + + pub fn set(&mut self, index: usize, value: u64) { + // Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)var1); + // Validate.inclusiveBetween(0L, this.mask, (long)var2); + // int var3 = this.cellIndex(var1); + // long var4 = this.data[var3]; + // int var6 = (var1 - var3 * this.valuesPerLong) * this.bits; + // this.data[var3] = var4 & ~(this.mask << var6) | ((long)var2 & this.mask) << var6; + + assert!(index <= self.size - 1); + assert!(value <= self.mask); + let cell_index = self.cell_index(index as u64); + let cell = &mut self.data[cell_index as usize]; + let bit_index = (index - cell_index * self.values_per_long as usize) * self.bits; + *cell = *cell & !(self.mask << bit_index) | (value & self.mask) << bit_index; + } } #[cfg(test)] @@ -144,6 +183,10 @@ mod tests { 1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2, ]; let expected_compact: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87]; - let storage = BitStorage::new(5, 10, None).unwrap(); + let storage = BitStorage::new(5, data.len(), Some(expected_compact.to_vec())).unwrap(); + + for (i, expected) in data.iter().enumerate() { + assert_eq!(storage.get(i), *expected); + } } } diff --git a/bot/src/main.rs b/bot/src/main.rs index 504c8d41..167f4edc 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -5,7 +5,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "172.23.192.1:65163"; + let address = "172.23.192.1:65111"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); From 4dac004635e50682d9ebe8812fdf654a0c1808f1 Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 5 May 2022 22:12:54 -0500 Subject: [PATCH 11/29] Fix chunk decoding --- azalea-protocol/src/mc_buf/mod.rs | 2 ++ azalea-protocol/src/mc_buf/read.rs | 11 ++++++ azalea-protocol/src/mc_buf/write.rs | 7 ++++ azalea-world/src/bit_storage.rs | 9 ++--- azalea-world/src/lib.rs | 19 +++++++--- azalea-world/src/palette.rs | 54 +++++++++++++++++++++++------ bot/src/main.rs | 2 +- 7 files changed, 85 insertions(+), 19 deletions(-) diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs index a82334fb..debf2991 100755 --- a/azalea-protocol/src/mc_buf/mod.rs +++ b/azalea-protocol/src/mc_buf/mod.rs @@ -12,6 +12,8 @@ pub use write::{McBufVarintWritable, McBufWritable, Writable}; const MAX_STRING_LENGTH: u16 = 32767; // const MAX_COMPONENT_STRING_LENGTH: u32 = 262144; +// TODO: maybe get rid of the readable/writable traits so there's not two ways to do the same thing and improve McBufReadable/McBufWritable + // TODO: have a definitions.rs in mc_buf that contains UnsizedByteArray and BitSet /// A Vec that isn't prefixed by a VarInt with the size. diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs index e1ae321c..a8c44bdf 100755 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -255,6 +255,17 @@ impl McBufVarintReadable for i32 { } } +impl McBufVarintReadable for Vec { + fn varint_read_into(buf: &mut impl Read) -> Result { + let length = u32::varint_read_into(buf)?; + let mut vec = Vec::with_capacity(length as usize); + for _ in 0..length { + vec.push(T::varint_read_into(buf)?); + } + Ok(vec) + } +} + impl McBufReadable for UnsizedByteArray { fn read_into(buf: &mut impl Read) -> Result { Ok(UnsizedByteArray(buf.read_bytes()?)) diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs index 3a4a02f8..cc5f2284 100755 --- a/azalea-protocol/src/mc_buf/write.rs +++ b/azalea-protocol/src/mc_buf/write.rs @@ -210,6 +210,13 @@ impl McBufVarintWritable for u32 { } } +// Vec varint +impl McBufVarintWritable for Vec { + fn varint_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + buf.write_list(self, |buf, i| i.varint_write_into(buf)) + } +} + // u16 impl McBufWritable for u16 { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 5ced67fe..9cc3a053 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fmt, ops::Index}; +use std::{error::Error, fmt}; // this is from minecraft's code // yeah idk either @@ -70,6 +70,7 @@ const MAGIC: [(i32, i32, i32); 64] = [ ]; /// A compact list of integers with the given number of bits per entry. +#[derive(Clone)] pub struct BitStorage { data: Vec, bits: usize, @@ -135,7 +136,7 @@ impl BitStorage { pub fn cell_index(&self, index: u64) -> usize { let first = self.divide_mul as u64; - let second = self.divide_mul as u64; + let second = self.divide_add as u64; (index * first + second >> 32 >> self.divide_shift) .try_into() @@ -182,8 +183,8 @@ mod tests { let data = [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2, ]; - let expected_compact: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87]; - let storage = BitStorage::new(5, data.len(), Some(expected_compact.to_vec())).unwrap(); + let compact_data: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87]; + let storage = BitStorage::new(5, data.len(), Some(compact_data.to_vec())).unwrap(); for (i, expected) in data.iter().enumerate() { assert_eq!(storage.get(i), *expected); diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 54961401..abeac181 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -11,6 +11,8 @@ use std::{ sync::{Arc, Mutex}, }; +use crate::palette::PalettedContainerType; + #[cfg(test)] mod tests { #[test] @@ -43,7 +45,7 @@ impl World { // let existing_chunk = &self.storage[pos]; let chunk = Arc::new(Mutex::new(Chunk::read_with_world(data, self)?)); - println!("Loaded chunk {:?}", chunk); + println!("Loaded chunk {:?}", pos); self.storage[pos] = Some(chunk); Ok(()) @@ -121,7 +123,9 @@ impl Chunk { pub fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { let section_count = world_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); - for _ in 0..section_count { + println!("\n\nreading {} sections", section_count); + for i in 0..section_count { + println!("reading section #{}", i); let section = Section::read_into(buf)?; sections.push(section); } @@ -148,8 +152,15 @@ pub struct Section { impl McBufReadable for Section { fn read_into(buf: &mut impl Read) -> Result { let block_count = u16::read_into(buf)?; - let states = PalettedContainer::read_into(buf)?; - let biomes = PalettedContainer::read_into(buf)?; + println!("block count: {}\n", block_count); + // assert!( + // block_count <= 16 * 16 * 16, + // "A section has more blocks than what should be possible. This is a bug!" + // ); + let states = PalettedContainer::read_with_type(buf, &PalettedContainerType::BlockStates)?; + println!("! read states, reading biomes next"); + let biomes = PalettedContainer::read_with_type(buf, &PalettedContainerType::Biomes)?; + println!(); Ok(Section { block_count, states, diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 69900fe6..47354c94 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -1,20 +1,43 @@ +use azalea_protocol::mc_buf::{ + McBufReadable, McBufVarintReadable, McBufWritable, Readable, Writable, +}; use std::io::{Read, Write}; -use azalea_protocol::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; +#[derive(Clone, Debug, Copy)] +pub enum PalettedContainerType { + Biomes, + BlockStates, +} #[derive(Clone, Debug)] pub struct PalettedContainer { pub bits_per_entry: u8, pub palette: Palette, /// Compacted list of indices pointing to entry IDs in the Palette. - pub data: Vec, + pub data: Vec, } -impl McBufReadable for PalettedContainer { - fn read_into(buf: &mut impl Read) -> Result { +impl PalettedContainer { + pub fn read_with_type( + buf: &mut impl Read, + type_: &'static PalettedContainerType, + ) -> Result { let bits_per_entry = buf.read_byte()?; - let palette = Palette::read_with_bits_per_entry(buf, bits_per_entry)?; - let data = Vec::::read_into(buf)?; + let palette = match type_ { + PalettedContainerType::BlockStates => { + Palette::block_states_read_with_bits_per_entry(buf, bits_per_entry)? + } + PalettedContainerType::Biomes => { + Palette::biomes_read_with_bits_per_entry(buf, bits_per_entry)? + } + }; + + let data = Vec::::read_into(buf)?; + debug_assert!( + bits_per_entry != 0 || data.is_empty(), + "Bits per entry is 0 but data is not empty." + ); + Ok(PalettedContainer { bits_per_entry, palette, @@ -41,14 +64,25 @@ pub enum Palette { } impl Palette { - pub fn read_with_bits_per_entry( + pub fn block_states_read_with_bits_per_entry( buf: &mut impl Read, bits_per_entry: u8, ) -> Result { Ok(match bits_per_entry { - 0 => Palette::SingleValue(u32::read_into(buf)?), - 1..=4 => Palette::Linear(Vec::::read_into(buf)?), - 5..=8 => Palette::Hashmap(Vec::::read_into(buf)?), + 0 => Palette::SingleValue(u32::varint_read_into(buf)?), + 1..=4 => Palette::Linear(Vec::::varint_read_into(buf)?), + 5..=8 => Palette::Hashmap(Vec::::varint_read_into(buf)?), + _ => Palette::Global, + }) + } + + pub fn biomes_read_with_bits_per_entry( + buf: &mut impl Read, + bits_per_entry: u8, + ) -> Result { + Ok(match bits_per_entry { + 0 => Palette::SingleValue(u32::varint_read_into(buf)?), + 1..=3 => Palette::Linear(Vec::::varint_read_into(buf)?), _ => Palette::Global, }) } diff --git a/bot/src/main.rs b/bot/src/main.rs index 167f4edc..7cf056bf 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -5,7 +5,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "172.23.192.1:65111"; + let address = "172.23.192.1:62522"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); From 1b48cad53ffba45463be41dafb4dfbcab0f46c09 Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 5 May 2022 23:06:37 -0500 Subject: [PATCH 12/29] remove some prints --- azalea-world/src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index abeac181..36bbceac 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -123,9 +123,7 @@ impl Chunk { pub fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { let section_count = world_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); - println!("\n\nreading {} sections", section_count); for i in 0..section_count { - println!("reading section #{}", i); let section = Section::read_into(buf)?; sections.push(section); } @@ -152,15 +150,13 @@ pub struct Section { impl McBufReadable for Section { fn read_into(buf: &mut impl Read) -> Result { let block_count = u16::read_into(buf)?; - println!("block count: {}\n", block_count); + // this is commented out because apparently the vanilla server just gives us an incorrect block count sometimes // assert!( // block_count <= 16 * 16 * 16, // "A section has more blocks than what should be possible. This is a bug!" // ); let states = PalettedContainer::read_with_type(buf, &PalettedContainerType::BlockStates)?; - println!("! read states, reading biomes next"); let biomes = PalettedContainer::read_with_type(buf, &PalettedContainerType::Biomes)?; - println!(); Ok(Section { block_count, states, From e0239865659b2f2750edda7556548f6a2b8d4127 Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 5 May 2022 23:33:08 -0500 Subject: [PATCH 13/29] random polish --- Cargo.lock | 1 + azalea-core/src/lib.rs | 2 +- azalea-core/src/position.rs | 13 +++++++++++++ azalea-world/src/lib.rs | 14 +++++++++++++- bot/Cargo.toml | 1 + bot/src/main.rs | 13 ++++++++++++- 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73a8dafd..e5b6a112 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,6 +191,7 @@ name = "bot" version = "0.1.0" dependencies = [ "azalea-client", + "azalea-core", "azalea-protocol", "tokio", ] diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs index 6f0c25cc..0053dc9b 100755 --- a/azalea-core/src/lib.rs +++ b/azalea-core/src/lib.rs @@ -9,7 +9,7 @@ mod slot; pub use slot::{Slot, SlotData}; mod position; -pub use position::{BlockPos, ChunkPos}; +pub use position::{BlockPos, ChunkPos, ChunkSectionPos}; mod direction; pub use direction::Direction; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index aa82c1f9..a57f5c0b 100644 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -22,3 +22,16 @@ impl ChunkPos { ChunkPos { x, z } } } + +#[derive(Clone, Copy, Debug, Default)] +pub struct ChunkSectionPos { + pub x: i32, + pub y: i32, + pub z: i32, +} + +impl ChunkSectionPos { + pub fn new(x: i32, y: i32, z: i32) -> Self { + ChunkSectionPos { x, y, z } + } +} diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 36bbceac..4b8c21e9 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -55,6 +55,18 @@ impl World { self.storage.view_center = *pos; } } +impl Index<&ChunkPos> for World { + type Output = Option>>; + + fn index(&self, pos: &ChunkPos) -> &Self::Output { + &self.storage[pos] + } +} +impl IndexMut<&ChunkPos> for World { + fn index_mut<'a>(&'a mut self, pos: &ChunkPos) -> &'a mut Self::Output { + &mut self.storage[pos] + } +} pub struct ChunkStorage { view_center: ChunkPos, @@ -150,7 +162,7 @@ pub struct Section { impl McBufReadable for Section { fn read_into(buf: &mut impl Read) -> Result { let block_count = u16::read_into(buf)?; - // this is commented out because apparently the vanilla server just gives us an incorrect block count sometimes + // this is commented out because the vanilla server is wrong // assert!( // block_count <= 16 * 16 * 16, // "A section has more blocks than what should be possible. This is a bug!" diff --git a/bot/Cargo.toml b/bot/Cargo.toml index fd6ad067..e55f6c3d 100755 --- a/bot/Cargo.toml +++ b/bot/Cargo.toml @@ -7,5 +7,6 @@ version = "0.1.0" [dependencies] azalea-client = {path = "../azalea-client"} +azalea-core = {path = "../azalea-core"} azalea-protocol = {path = "../azalea-protocol"} tokio = "^1.14.0" diff --git a/bot/src/main.rs b/bot/src/main.rs index 7cf056bf..657d1adb 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -1,4 +1,5 @@ use azalea_client::{Account, Event}; +use azalea_core::ChunkPos; #[tokio::main] async fn main() { @@ -17,7 +18,17 @@ async fn main() { while let Some(e) = client.next().await { match e { - Event::Login => {} + // TODO: have a "loaded" or "ready" event that fires when all chunks are loaded + Event::Login => { + // let state = client.state.lock().await; + // let world = state.world.as_ref().unwrap(); + // let c = world[&ChunkPos::new(-1, -4)] + // .as_ref() + // .unwrap() + // .lock() + // .unwrap(); + // println!("{:?}", c); + } } } From d9795a593aa51b7cd5e2d98484c05d9345eed71d Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 8 May 2022 18:55:56 -0500 Subject: [PATCH 14/29] Update palette.rs --- azalea-world/src/palette.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 47354c94..db722a5b 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -1,6 +1,4 @@ -use azalea_protocol::mc_buf::{ - McBufReadable, McBufVarintReadable, McBufWritable, Readable, Writable, -}; +use azalea_protocol::mc_buf::{McBufReadable, McBufVarReadable, McBufWritable, Readable, Writable}; use std::io::{Read, Write}; #[derive(Clone, Debug, Copy)] @@ -69,9 +67,9 @@ impl Palette { bits_per_entry: u8, ) -> Result { Ok(match bits_per_entry { - 0 => Palette::SingleValue(u32::varint_read_into(buf)?), - 1..=4 => Palette::Linear(Vec::::varint_read_into(buf)?), - 5..=8 => Palette::Hashmap(Vec::::varint_read_into(buf)?), + 0 => Palette::SingleValue(u32::var_read_into(buf)?), + 1..=4 => Palette::Linear(Vec::::var_read_into(buf)?), + 5..=8 => Palette::Hashmap(Vec::::var_read_into(buf)?), _ => Palette::Global, }) } @@ -81,8 +79,8 @@ impl Palette { bits_per_entry: u8, ) -> Result { Ok(match bits_per_entry { - 0 => Palette::SingleValue(u32::varint_read_into(buf)?), - 1..=3 => Palette::Linear(Vec::::varint_read_into(buf)?), + 0 => Palette::SingleValue(u32::var_read_into(buf)?), + 1..=3 => Palette::Linear(Vec::::var_read_into(buf)?), _ => Palette::Global, }) } From a3e26b38bd147efea16d592536aaece37e3e2741 Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 8 May 2022 19:00:51 -0500 Subject: [PATCH 15/29] fix saving being slow --- azalea-language/src/lib.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/azalea-language/src/lib.rs b/azalea-language/src/lib.rs index 3647d4c7..7aa91405 100644 --- a/azalea-language/src/lib.rs +++ b/azalea-language/src/lib.rs @@ -1,5 +1,5 @@ use lazy_static::lazy_static; -use std::collections::HashMap; +use std::{collections::HashMap, fs::File}; // use tokio::fs::File; @@ -29,8 +29,13 @@ use std::collections::HashMap; // The code above is kept in case I come up with a better solution lazy_static! { - pub static ref STORAGE: HashMap = - serde_json::from_str(include_str!("en_us.json")).unwrap(); + pub static ref STORAGE: HashMap = serde_json::from_str({ + let mut file = File::open("en_us.json").unwrap(); + let mut contents = String::new(); + file.read_to_string(&mut contents).unwrap(); + contents + }) + .unwrap(); } pub fn get(key: &str) -> Option<&str> { From 718bea869679a73a256edcb1a1349625218d2e34 Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 8 May 2022 19:02:01 -0500 Subject: [PATCH 16/29] fix the fix --- azalea-language/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azalea-language/src/lib.rs b/azalea-language/src/lib.rs index 7aa91405..c0ac4c4f 100644 --- a/azalea-language/src/lib.rs +++ b/azalea-language/src/lib.rs @@ -1,6 +1,6 @@ use lazy_static::lazy_static; +use std::io::Read; use std::{collections::HashMap, fs::File}; - // use tokio::fs::File; // pub struct Language { @@ -29,7 +29,7 @@ use std::{collections::HashMap, fs::File}; // The code above is kept in case I come up with a better solution lazy_static! { - pub static ref STORAGE: HashMap = serde_json::from_str({ + pub static ref STORAGE: HashMap = serde_json::from_str(&{ let mut file = File::open("en_us.json").unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); From 122693a654b0c851bbb9e134c539961419175bef Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 8 May 2022 19:19:20 -0500 Subject: [PATCH 17/29] actually actually fix --- azalea-language/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/azalea-language/src/lib.rs b/azalea-language/src/lib.rs index c0ac4c4f..b48a0a6b 100644 --- a/azalea-language/src/lib.rs +++ b/azalea-language/src/lib.rs @@ -1,5 +1,6 @@ use lazy_static::lazy_static; use std::io::Read; +use std::path::Path; use std::{collections::HashMap, fs::File}; // use tokio::fs::File; @@ -30,7 +31,9 @@ use std::{collections::HashMap, fs::File}; lazy_static! { pub static ref STORAGE: HashMap = serde_json::from_str(&{ - let mut file = File::open("en_us.json").unwrap(); + let src_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/src/en_us.json")); + println!("dir: {:?}", src_dir); + let mut file = File::open(src_dir).unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); contents @@ -41,3 +44,13 @@ lazy_static! { pub fn get(key: &str) -> Option<&str> { STORAGE.get(key).map(|s| s.as_str()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get() { + assert_eq!(get("translation.test.none"), Some("Hello, world!")); + } +} From 345cecf7afa84df2d5ecf075ecfb499e3fd10a55 Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 8 May 2022 23:45:15 -0500 Subject: [PATCH 18/29] add more stuff --- .gitignore | 2 -- azalea-client/src/connect.rs | 1 - azalea-core/src/position.rs | 25 +++++++++++++++++++++++++ azalea-world/src/bit_storage.rs | 12 ++++++++++-- azalea-world/src/lib.rs | 9 +++++++++ azalea-world/src/palette.rs | 14 +++++++++++--- bot/src/main.rs | 23 ++++++++++++----------- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index dc2a59d1..53141060 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,6 @@ flamegraph.svg perf.data perf.data.old -# TODO: remove this after chunk-decoding is merged -/login.txt code-generator/Burger code-generator/client.jar diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 2f38b305..522d7d48 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -177,7 +177,6 @@ impl Client { match packet { GamePacket::ClientboundLoginPacket(p) => { println!("Got login packet {:?}", p); - std::fs::write("login.txt", format!("{:#?}", p)).expect("Unable to write file"); let mut state = state.lock().await; state.player.entity.id = p.player_id; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index a57f5c0b..a2292651 100644 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -23,6 +23,15 @@ impl ChunkPos { } } +impl From for ChunkPos { + fn from(pos: BlockPos) -> Self { + ChunkPos { + x: pos.x / 16, + z: pos.z / 16, + } + } +} + #[derive(Clone, Copy, Debug, Default)] pub struct ChunkSectionPos { pub x: i32, @@ -35,3 +44,19 @@ impl ChunkSectionPos { ChunkSectionPos { x, y, z } } } + +impl From for ChunkSectionPos { + fn from(pos: BlockPos) -> Self { + ChunkSectionPos { + x: pos.x / 16, + y: pos.y / 16, + z: pos.z / 16, + } + } +} + +impl From for ChunkPos { + fn from(pos: ChunkSectionPos) -> Self { + ChunkPos { x: pos.x, z: pos.z } + } +} diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 9cc3a053..211a4a04 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -70,9 +70,9 @@ const MAGIC: [(i32, i32, i32); 64] = [ ]; /// A compact list of integers with the given number of bits per entry. -#[derive(Clone)] +#[derive(Clone, Debug, Default)] pub struct BitStorage { - data: Vec, + pub data: Vec, bits: usize, mask: u64, size: usize, @@ -103,9 +103,17 @@ impl BitStorage { /// Create a new BitStorage with the given number of bits per entry. /// `size` is the number of entries in the BitStorage. pub fn new(bits: usize, size: usize, data: Option>) -> Result { + if let Some(data) = &data { + if data.len() == 0 { + // TODO: make 0 bit storage actually work + return Ok(BitStorage::default()); + } + } + let values_per_long = 64 / bits; let magic_index = values_per_long - 1; let (divide_mul, divide_add, divide_shift) = MAGIC[magic_index as usize]; + println!("values_per_long: {}, size: {}", values_per_long, size); let calculated_length = (size + values_per_long - 1) / values_per_long; let mask = (1 << bits) - 1; diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 4b8c21e9..4da2fb0f 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -67,6 +67,15 @@ impl IndexMut<&ChunkPos> for World { &mut self.storage[pos] } } +// impl Index<&BlockPos> for World { +// type Output = Option>>; + +// fn index(&self, pos: &BlockPos) -> &Self::Output { +// let chunk = &self[ChunkPos::from(pos)]; +// // chunk. + +// } +// } pub struct ChunkStorage { view_center: ChunkPos, diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index db722a5b..c33992b1 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -1,6 +1,8 @@ use azalea_protocol::mc_buf::{McBufReadable, McBufVarReadable, McBufWritable, Readable, Writable}; use std::io::{Read, Write}; +use crate::BitStorage; + #[derive(Clone, Debug, Copy)] pub enum PalettedContainerType { Biomes, @@ -12,7 +14,7 @@ pub struct PalettedContainer { pub bits_per_entry: u8, pub palette: Palette, /// Compacted list of indices pointing to entry IDs in the Palette. - pub data: Vec, + pub storage: BitStorage, } impl PalettedContainer { @@ -29,17 +31,23 @@ impl PalettedContainer { Palette::biomes_read_with_bits_per_entry(buf, bits_per_entry)? } }; + let size = match type_ { + PalettedContainerType::BlockStates => 4096, + PalettedContainerType::Biomes => 64, + }; let data = Vec::::read_into(buf)?; debug_assert!( bits_per_entry != 0 || data.is_empty(), "Bits per entry is 0 but data is not empty." ); + println!("data: {:?}", data); + let storage = BitStorage::new(bits_per_entry.into(), size, Some(data)).unwrap(); Ok(PalettedContainer { bits_per_entry, palette, - data, + storage, }) } } @@ -47,7 +55,7 @@ impl McBufWritable for PalettedContainer { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(self.bits_per_entry)?; self.palette.write_into(buf)?; - self.data.write_into(buf)?; + self.storage.data.write_into(buf)?; Ok(()) } } diff --git a/bot/src/main.rs b/bot/src/main.rs index 075bfa44..2686636b 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -1,5 +1,5 @@ use azalea_client::{Account, Event}; -use azalea_core::ChunkPos; +use azalea_core::{BlockPos, ChunkPos}; #[tokio::main] async fn main() { @@ -19,18 +19,19 @@ async fn main() { while let Some(e) = client.next().await { match e { // TODO: have a "loaded" or "ready" event that fires when all chunks are loaded - Event::Login => { - // let state = client.state.lock().await; - // let world = state.world.as_ref().unwrap(); - // let c = world[&ChunkPos::new(-1, -4)] - // .as_ref() - // .unwrap() - // .lock() - // .unwrap(); - // println!("{:?}", c); - } + Event::Login => {} Event::Chat(p) => { println!("{}", p.message.to_ansi(None)); + if p.message.to_ansi(None) == " ok" { + let state = client.state.lock().await; + let world = state.world.as_ref().unwrap(); + // let c = world[&BlockPos::new(5, 78, -2)] + // .as_ref() + // .unwrap() + // .lock() + // .unwrap(); + // println!("{:?}", c); + } } } } From 7c194fb245fac1c52fbb9e4ca042dd5c42d522b6 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 11:20:33 -0500 Subject: [PATCH 19/29] remove some printlns --- azalea-language/src/lib.rs | 1 - azalea-world/src/bit_storage.rs | 1 - azalea-world/src/palette.rs | 1 - bot/src/main.rs | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/azalea-language/src/lib.rs b/azalea-language/src/lib.rs index b48a0a6b..f54de3cb 100644 --- a/azalea-language/src/lib.rs +++ b/azalea-language/src/lib.rs @@ -32,7 +32,6 @@ use std::{collections::HashMap, fs::File}; lazy_static! { pub static ref STORAGE: HashMap = serde_json::from_str(&{ let src_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/src/en_us.json")); - println!("dir: {:?}", src_dir); let mut file = File::open(src_dir).unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 211a4a04..3f810f40 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -113,7 +113,6 @@ impl BitStorage { let values_per_long = 64 / bits; let magic_index = values_per_long - 1; let (divide_mul, divide_add, divide_shift) = MAGIC[magic_index as usize]; - println!("values_per_long: {}, size: {}", values_per_long, size); let calculated_length = (size + values_per_long - 1) / values_per_long; let mask = (1 << bits) - 1; diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index c33992b1..55a33bde 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -41,7 +41,6 @@ impl PalettedContainer { bits_per_entry != 0 || data.is_empty(), "Bits per entry is 0 but data is not empty." ); - println!("data: {:?}", data); let storage = BitStorage::new(bits_per_entry.into(), size, Some(data)).unwrap(); Ok(PalettedContainer { diff --git a/bot/src/main.rs b/bot/src/main.rs index 2686636b..2f9fb9e6 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -6,7 +6,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "172.23.192.1:61385"; + let address = "192.168.2.234:62840"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); From 6d2fd8afbad44bbe88f701e1d67cc2f251246c07 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 14:12:57 -0500 Subject: [PATCH 20/29] start adding get_block_state --- azalea-core/src/lib.rs | 2 +- azalea-core/src/position.rs | 43 +++++++++++++++++++++++++++++++-- azalea-world/src/bit_storage.rs | 16 +++++++++--- azalea-world/src/lib.rs | 43 ++++++++++++++++++++++++++++++--- azalea-world/src/palette.rs | 30 +++++++++++++++++++++++ bot/src/main.rs | 8 ++---- 6 files changed, 127 insertions(+), 15 deletions(-) diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs index 0053dc9b..2b12db53 100755 --- a/azalea-core/src/lib.rs +++ b/azalea-core/src/lib.rs @@ -9,7 +9,7 @@ mod slot; pub use slot::{Slot, SlotData}; mod position; -pub use position::{BlockPos, ChunkPos, ChunkSectionPos}; +pub use position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos}; mod direction; pub use direction::Direction; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index a2292651..1dd200ab 100644 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -1,3 +1,5 @@ +use std::ops::Rem; + #[derive(Clone, Copy, Debug, Default)] pub struct BlockPos { pub x: i32, @@ -11,6 +13,18 @@ impl BlockPos { } } +impl Rem for BlockPos { + type Output = Self; + + fn rem(self, rhs: i32) -> Self { + BlockPos { + x: self.x % rhs, + y: self.y % rhs, + z: self.z % rhs, + } + } +} + #[derive(Clone, Copy, Debug, Default)] pub struct ChunkPos { pub x: i32, @@ -23,8 +37,8 @@ impl ChunkPos { } } -impl From for ChunkPos { - fn from(pos: BlockPos) -> Self { +impl From<&BlockPos> for ChunkPos { + fn from(pos: &BlockPos) -> Self { ChunkPos { x: pos.x / 16, z: pos.z / 16, @@ -32,6 +46,7 @@ impl From for ChunkPos { } } +/// The coordinates of a chunk section in the world. #[derive(Clone, Copy, Debug, Default)] pub struct ChunkSectionPos { pub x: i32, @@ -60,3 +75,27 @@ impl From for ChunkPos { ChunkPos { x: pos.x, z: pos.z } } } + +/// The coordinates of a block inside a chunk section. +#[derive(Clone, Copy, Debug, Default)] +pub struct ChunkSectionBlockPos { + pub x: u8, + pub y: u8, + pub z: u8, +} + +impl ChunkSectionBlockPos { + pub fn new(x: u8, y: u8, z: u8) -> Self { + ChunkSectionBlockPos { x, y, z } + } +} + +impl From<&BlockPos> for ChunkSectionBlockPos { + fn from(pos: &BlockPos) -> Self { + ChunkSectionBlockPos { + x: pos.x.rem(16).abs() as u8, + y: pos.y.rem(16).abs() as u8, + z: pos.z.rem(16).abs() as u8, + } + } +} diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 3f810f40..f24a0514 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -103,6 +103,9 @@ impl BitStorage { /// Create a new BitStorage with the given number of bits per entry. /// `size` is the number of entries in the BitStorage. pub fn new(bits: usize, size: usize, data: Option>) -> Result { + // vanilla has this assert but it's not always true for some reason?? + // assert!(bits >= 1 && bits <= 32); + if let Some(data) = &data { if data.len() == 0 { // TODO: make 0 bit storage actually work @@ -142,10 +145,12 @@ impl BitStorage { } pub fn cell_index(&self, index: u64) -> usize { - let first = self.divide_mul as u64; + // as unsigned wrap + let first = self.divide_mul as u32 as u64; let second = self.divide_add as u64; + dbg!(first, second, index); - (index * first + second >> 32 >> self.divide_shift) + (((index * first) + second) >> 32 >> self.divide_shift) .try_into() .unwrap() } @@ -157,7 +162,12 @@ impl BitStorage { // int var5 = (var1 - var2 * this.valuesPerLong) * this.bits; // return (int)(var3 >> var5 & this.mask); - assert!(index <= self.size - 1); + assert!( + index <= self.size - 1, + "Index {} out of bounds (max is {})", + index, + self.size - 1 + ); let cell_index = self.cell_index(index as u64); let cell = &self.data[cell_index as usize]; let bit_index = (index - cell_index * self.values_per_long as usize) * self.bits; diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 4da2fb0f..aa99a470 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,7 +1,8 @@ mod bit_storage; mod palette; -use azalea_core::ChunkPos; +use crate::palette::PalettedContainerType; +use azalea_core::{BlockPos, ChunkPos, ChunkSectionBlockPos}; use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; pub use bit_storage::BitStorage; use palette::PalettedContainer; @@ -11,8 +12,6 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::palette::PalettedContainerType; - #[cfg(test)] mod tests { #[test] @@ -54,6 +53,10 @@ impl World { pub fn update_view_center(&mut self, pos: &ChunkPos) { self.storage.view_center = *pos; } + + pub fn get_block_state(&self, pos: &BlockPos) -> Option { + self.storage.get_block_state(pos) + } } impl Index<&ChunkPos> for World { type Output = Option>>; @@ -115,6 +118,15 @@ impl ChunkStorage { (chunk_pos.x - self.view_center.x).unsigned_abs() <= self.chunk_radius && (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius } + + pub fn get_block_state(&self, pos: &BlockPos) -> Option { + let chunk_pos = ChunkPos::from(pos); + let chunk = &self[&chunk_pos]; + match chunk { + Some(chunk) => Some(chunk.lock().unwrap().get(pos)), + None => None, + } + } } impl Index<&ChunkPos> for ChunkStorage { @@ -150,6 +162,23 @@ impl Chunk { } Ok(Chunk { sections }) } + + pub fn section_index(&self, y: i32) -> u32 { + // TODO: check the build height and stuff, this code will be broken if the min build height is 0 + // (LevelHeightAccessor.getMinSection in vanilla code) + assert!(y >= 0); + (y as u32) / 16 + } + + pub fn get(&self, pos: &BlockPos) -> u32 { + let section_index = self.section_index(pos.y); + println!("section index: {}", section_index); + // TODO: make sure the section exists + let section = &self.sections[section_index as usize]; + let chunk_section_pos = ChunkSectionBlockPos::from(pos); + let block_state = section.get(chunk_section_pos); + block_state + } } impl McBufWritable for Chunk { @@ -194,3 +223,11 @@ impl McBufWritable for Section { Ok(()) } } + +impl Section { + // TODO: return a BlockState instead of a u32 + fn get(&self, pos: ChunkSectionBlockPos) -> u32 { + self.states + .get(pos.x as usize, pos.y as usize, pos.z as usize) + } +} diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 55a33bde..6dc5e183 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -15,6 +15,7 @@ pub struct PalettedContainer { pub palette: Palette, /// Compacted list of indices pointing to entry IDs in the Palette. pub storage: BitStorage, + pub container_type: PalettedContainerType, } impl PalettedContainer { @@ -47,9 +48,29 @@ impl PalettedContainer { bits_per_entry, palette, storage, + container_type: *type_, }) } + + pub fn get_index(&self, x: usize, y: usize, z: usize) -> usize { + let size_bits = match self.container_type { + PalettedContainerType::BlockStates => 4, + PalettedContainerType::Biomes => 2, + }; + + (((y << size_bits) | z) << size_bits) | x + } + + pub fn get(&self, x: usize, y: usize, z: usize) -> u32 { + println!( + "get: {} {} {}, bits per entry: {}", + x, y, z, self.bits_per_entry + ); + let paletted_value = self.storage.get(self.get_index(x, y, z)); + self.palette.value_for(paletted_value as usize) + } } + impl McBufWritable for PalettedContainer { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(self.bits_per_entry)?; @@ -91,6 +112,15 @@ impl Palette { _ => Palette::Global, }) } + + pub fn value_for(&self, value: usize) -> u32 { + match self { + Palette::SingleValue(v) => *v, + Palette::Linear(v) => v[value], + Palette::Hashmap(v) => v[value], + Palette::Global => value as u32, + } + } } impl McBufWritable for Palette { diff --git a/bot/src/main.rs b/bot/src/main.rs index 2f9fb9e6..93d83be9 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -25,12 +25,8 @@ async fn main() { if p.message.to_ansi(None) == " ok" { let state = client.state.lock().await; let world = state.world.as_ref().unwrap(); - // let c = world[&BlockPos::new(5, 78, -2)] - // .as_ref() - // .unwrap() - // .lock() - // .unwrap(); - // println!("{:?}", c); + let c = world.get_block_state(&BlockPos::new(5, 78, -2)).unwrap(); + println!("{:?}", c); } } } From e58c9390a717517db0bf4366c55a3802c832b144 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 15:02:13 -0500 Subject: [PATCH 21/29] get_block_state works --- azalea-client/src/connect.rs | 8 ++++ azalea-core/src/difficulty.rs | 1 - azalea-core/src/lib.rs | 4 +- azalea-core/src/position.rs | 68 ++++++++++++++++++++++++++++++--- azalea-world/src/bit_storage.rs | 1 - azalea-world/src/lib.rs | 24 +++++++----- azalea-world/src/palette.rs | 5 +-- bot/src/main.rs | 2 +- 8 files changed, 90 insertions(+), 23 deletions(-) diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 522d7d48..8d2e9dc1 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -195,9 +195,17 @@ impl Client { .expect("height tag is not int")) .try_into() .expect("height is not a u32"); + let min_y = (*dimension_type + .get("min_y") + .expect("No min_y tag") + .as_int() + .expect("min_y tag is not int")) + .try_into() + .expect("min_y is not an i32"); state.world = Some(World { height, + min_y, storage: ChunkStorage::new(16), }); diff --git a/azalea-core/src/difficulty.rs b/azalea-core/src/difficulty.rs index 21e980ba..5d869325 100755 --- a/azalea-core/src/difficulty.rs +++ b/azalea-core/src/difficulty.rs @@ -83,7 +83,6 @@ mod tests { assert_eq!(1, Difficulty::EASY.id()); assert_eq!(2, Difficulty::NORMAL.id()); assert_eq!(3, Difficulty::HARD.id()); - assert_eq!(4, Difficulty::PEACEFUL.id()); } #[test] diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs index 2b12db53..d2a2d558 100755 --- a/azalea-core/src/lib.rs +++ b/azalea-core/src/lib.rs @@ -1,5 +1,7 @@ //! Random miscellaneous things like UUIDs that don't deserve their own crate. +#![feature(int_roundings)] + pub mod difficulty; pub mod game_type; pub mod resource_location; @@ -9,7 +11,7 @@ mod slot; pub use slot::{Slot, SlotData}; mod position; -pub use position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos}; +pub use position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos}; mod direction; pub use direction::Direction; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index 1dd200ab..9c7cd132 100644 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -25,7 +25,7 @@ impl Rem for BlockPos { } } -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct ChunkPos { pub x: i32, pub z: i32, @@ -40,8 +40,8 @@ impl ChunkPos { impl From<&BlockPos> for ChunkPos { fn from(pos: &BlockPos) -> Self { ChunkPos { - x: pos.x / 16, - z: pos.z / 16, + x: pos.x.div_floor(16), + z: pos.z.div_floor(16), } } } @@ -63,9 +63,9 @@ impl ChunkSectionPos { impl From for ChunkSectionPos { fn from(pos: BlockPos) -> Self { ChunkSectionPos { - x: pos.x / 16, - y: pos.y / 16, - z: pos.z / 16, + x: pos.x.div_floor(16), + y: pos.y.div_floor(16), + z: pos.z.div_floor(16), } } } @@ -76,11 +76,38 @@ impl From for ChunkPos { } } +/// The coordinates of a block inside a chunk. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct ChunkBlockPos { + pub x: u8, + pub y: i32, + pub z: u8, +} + +impl ChunkBlockPos { + pub fn new(x: u8, y: i32, z: u8) -> Self { + ChunkBlockPos { x, y, z } + } +} + +impl From<&BlockPos> for ChunkBlockPos { + fn from(pos: &BlockPos) -> Self { + ChunkBlockPos { + x: pos.x.rem_euclid(16).abs() as u8, + y: pos.y, + z: pos.z.rem_euclid(16).abs() as u8, + } + } +} + /// The coordinates of a block inside a chunk section. #[derive(Clone, Copy, Debug, Default)] pub struct ChunkSectionBlockPos { + /// A number between 0 and 16. pub x: u8, + /// A number between 0 and 16. pub y: u8, + /// A number between 0 and 16. pub z: u8, } @@ -99,3 +126,32 @@ impl From<&BlockPos> for ChunkSectionBlockPos { } } } + +impl From<&ChunkBlockPos> for ChunkSectionBlockPos { + fn from(pos: &ChunkBlockPos) -> Self { + ChunkSectionBlockPos { + x: pos.x, + y: pos.y.rem(16).abs() as u8, + z: pos.z, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_from_block_pos_to_chunk_pos() { + let block_pos = BlockPos::new(5, 78, -2); + let chunk_pos = ChunkPos::from(&block_pos); + assert_eq!(chunk_pos, ChunkPos::new(0, -1)); + } + + #[test] + fn test_from_block_pos_to_chunk_block_pos() { + let block_pos = BlockPos::new(5, 78, -2); + let chunk_block_pos = ChunkBlockPos::from(&block_pos); + assert_eq!(chunk_block_pos, ChunkBlockPos::new(5, 78, 14)); + } +} diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index f24a0514..aba52aef 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -148,7 +148,6 @@ impl BitStorage { // as unsigned wrap let first = self.divide_mul as u32 as u64; let second = self.divide_add as u64; - dbg!(first, second, index); (((index * first) + second) >> 32 >> self.divide_shift) .try_into() diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index aa99a470..4641729c 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,8 +1,10 @@ +#![feature(int_roundings)] + mod bit_storage; mod palette; use crate::palette::PalettedContainerType; -use azalea_core::{BlockPos, ChunkPos, ChunkSectionBlockPos}; +use azalea_core::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos}; use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; pub use bit_storage::BitStorage; use palette::PalettedContainer; @@ -26,6 +28,7 @@ const SECTION_HEIGHT: u32 = 16; pub struct World { pub storage: ChunkStorage, pub height: u32, + pub min_y: i32, } impl World { @@ -55,7 +58,7 @@ impl World { } pub fn get_block_state(&self, pos: &BlockPos) -> Option { - self.storage.get_block_state(pos) + self.storage.get_block_state(pos, self.min_y) } } impl Index<&ChunkPos> for World { @@ -119,11 +122,12 @@ impl ChunkStorage { && (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius } - pub fn get_block_state(&self, pos: &BlockPos) -> Option { + pub fn get_block_state(&self, pos: &BlockPos, min_y: i32) -> Option { let chunk_pos = ChunkPos::from(pos); + println!("chunk_pos {:?} block_pos {:?}", chunk_pos, pos); let chunk = &self[&chunk_pos]; match chunk { - Some(chunk) => Some(chunk.lock().unwrap().get(pos)), + Some(chunk) => Some(chunk.lock().unwrap().get(&ChunkBlockPos::from(pos), min_y)), None => None, } } @@ -156,26 +160,28 @@ impl Chunk { pub fn read_with_world_height(buf: &mut impl Read, world_height: u32) -> Result { let section_count = world_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); - for i in 0..section_count { + for _ in 0..section_count { let section = Section::read_into(buf)?; sections.push(section); } Ok(Chunk { sections }) } - pub fn section_index(&self, y: i32) -> u32 { + pub fn section_index(&self, y: i32, min_y: i32) -> u32 { // TODO: check the build height and stuff, this code will be broken if the min build height is 0 // (LevelHeightAccessor.getMinSection in vanilla code) assert!(y >= 0); - (y as u32) / 16 + let min_section_index = min_y.div_floor(16); + (y.div_floor(16) - min_section_index) as u32 } - pub fn get(&self, pos: &BlockPos) -> u32 { - let section_index = self.section_index(pos.y); + pub fn get(&self, pos: &ChunkBlockPos, min_y: i32) -> u32 { + let section_index = self.section_index(pos.y, min_y); println!("section index: {}", section_index); // TODO: make sure the section exists let section = &self.sections[section_index as usize]; let chunk_section_pos = ChunkSectionBlockPos::from(pos); + println!("chunk section pos: {:?}", chunk_section_pos); let block_state = section.get(chunk_section_pos); block_state } diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 6dc5e183..be6f022c 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -62,11 +62,8 @@ impl PalettedContainer { } pub fn get(&self, x: usize, y: usize, z: usize) -> u32 { - println!( - "get: {} {} {}, bits per entry: {}", - x, y, z, self.bits_per_entry - ); let paletted_value = self.storage.get(self.get_index(x, y, z)); + println!("palette: {:?}", self.palette); self.palette.value_for(paletted_value as usize) } } diff --git a/bot/src/main.rs b/bot/src/main.rs index 93d83be9..1f2cb6e1 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -26,7 +26,7 @@ async fn main() { let state = client.state.lock().await; let world = state.world.as_ref().unwrap(); let c = world.get_block_state(&BlockPos::new(5, 78, -2)).unwrap(); - println!("{:?}", c); + println!("block state: {:?}", c); } } } From 8fb95866093245bd802bebec08148c87f1188db3 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 18:55:08 -0500 Subject: [PATCH 22/29] remove some console.logs --- azalea-world/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 4641729c..766c61f0 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -177,11 +177,9 @@ impl Chunk { pub fn get(&self, pos: &ChunkBlockPos, min_y: i32) -> u32 { let section_index = self.section_index(pos.y, min_y); - println!("section index: {}", section_index); // TODO: make sure the section exists let section = &self.sections[section_index as usize]; let chunk_section_pos = ChunkSectionBlockPos::from(pos); - println!("chunk section pos: {:?}", chunk_section_pos); let block_state = section.get(chunk_section_pos); block_state } From 42f86f73f256c0219a923c5ff67a509e7a8a898d Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 19:14:34 -0500 Subject: [PATCH 23/29] add unhandled ClientboundSectionBlocksUpdatePacket --- azalea-client/src/connect.rs | 3 +++ azalea-protocol/src/mc_buf/read.rs | 14 +++++++++++++- azalea-protocol/src/mc_buf/write.rs | 13 ++++++++++++- .../clientbound_section_blocks_update_packet.rs | 10 ++++++++++ azalea-protocol/src/packets/game/mod.rs | 2 ++ bot/src/main.rs | 4 ++-- 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 8d2e9dc1..48fd16f2 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -373,6 +373,9 @@ impl Client { GamePacket::ClientboundAnimatePacket(p) => { println!("Got animate packet {:?}", p); } + GamePacket::ClientboundSectionBlocksUpdatePacket(p) => { + println!("Got section blocks update packet {:?}", p); + } _ => panic!("Unexpected packet {:?}", packet), } } diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs index ebafad92..1c4fbd6f 100644 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -2,7 +2,7 @@ use super::{UnsizedByteArray, MAX_STRING_LENGTH}; use azalea_chat::component::Component; use azalea_core::{ difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, - serializable_uuid::SerializableUuid, BlockPos, Direction, Slot, SlotData, + serializable_uuid::SerializableUuid, BlockPos, ChunkSectionPos, Direction, Slot, SlotData, }; use byteorder::{ReadBytesExt, BE}; use serde::Deserialize; @@ -518,3 +518,15 @@ impl McBufReadable for Direction { } } } + +// ChunkSectionPos +impl McBufReadable for ChunkSectionPos { + fn read_into(buf: &mut impl Read) -> Result { + let long = i64::read_into(buf)?; + Ok(ChunkSectionPos { + x: (long >> 42) as i32, + y: (long << 44 >> 44) as i32, + z: (long << 22 >> 42) as i32, + }) + } +} diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs index 7fe61752..c46297a6 100644 --- a/azalea-protocol/src/mc_buf/write.rs +++ b/azalea-protocol/src/mc_buf/write.rs @@ -2,7 +2,7 @@ use super::{UnsizedByteArray, MAX_STRING_LENGTH}; use azalea_chat::component::Component; use azalea_core::{ difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, - serializable_uuid::SerializableUuid, BlockPos, Direction, Slot, + serializable_uuid::SerializableUuid, BlockPos, ChunkSectionPos, Direction, Slot, }; use byteorder::{BigEndian, WriteBytesExt}; use std::{collections::HashMap, io::Write}; @@ -425,3 +425,14 @@ impl McBufWritable for Direction { buf.write_varint(*self as i32) } } + +// ChunkSectionPos +impl McBufWritable for ChunkSectionPos { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let long = (((self.x & 0x3FFFFF) as i64) << 42) + | (self.y & 0xFFFFF) as i64 + | (((self.z & 0x3FFFFF) as i64) << 20); + long.write_into(buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs new file mode 100644 index 00000000..f220b07f --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs @@ -0,0 +1,10 @@ +use azalea_core::ChunkSectionPos; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, GamePacket)] +pub struct ClientboundSectionBlocksUpdatePacket { + pub section_pos: ChunkSectionPos, + pub suppress_light_updates: bool, + #[var] + pub states: Vec, +} diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index 0391ee10..66c55cd2 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -26,6 +26,7 @@ pub mod clientbound_player_position_packet; pub mod clientbound_recipe_packet; pub mod clientbound_remove_entities_packet; pub mod clientbound_rotate_head_packet; +pub mod clientbound_section_blocks_update_packet; pub mod clientbound_set_carried_item_packet; pub mod clientbound_set_chunk_cache_center; pub mod clientbound_set_default_spawn_position_packet; @@ -80,6 +81,7 @@ declare_state_packets!( 0x39: clientbound_recipe_packet::ClientboundRecipePacket, 0x3a: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket, 0x3e: clientbound_rotate_head_packet::ClientboundRotateHeadPacket, + 0x3f: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket, 0x48: clientbound_set_carried_item_packet::ClientboundSetCarriedItemPacket, 0x49: clientbound_set_chunk_cache_center::ClientboundSetChunkCacheCenterPacket, 0x4a: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket, diff --git a/bot/src/main.rs b/bot/src/main.rs index 1f2cb6e1..76a5a15d 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -1,12 +1,12 @@ use azalea_client::{Account, Event}; -use azalea_core::{BlockPos, ChunkPos}; +use azalea_core::BlockPos; #[tokio::main] async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "192.168.2.234:62840"; + let address = "192.168.2.234:50736"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); From 2eaccf03eb8cc6227b287bb2da87fab14b16c94f Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 19:31:34 -0500 Subject: [PATCH 24/29] actually do ClientboundSectionBlocksUpdatePacket --- azalea-client/src/connect.rs | 2 + ...lientbound_section_blocks_update_packet.rs | 39 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 48fd16f2..7f245746 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -369,12 +369,14 @@ impl Client { } GamePacket::ClientboundBlockUpdatePacket(p) => { println!("Got block update packet {:?}", p); + // TODO: update world } GamePacket::ClientboundAnimatePacket(p) => { println!("Got animate packet {:?}", p); } GamePacket::ClientboundSectionBlocksUpdatePacket(p) => { println!("Got section blocks update packet {:?}", p); + // TODO: update world } _ => panic!("Unexpected packet {:?}", packet), } diff --git a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs index f220b07f..7f57a126 100644 --- a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs @@ -1,10 +1,43 @@ -use azalea_core::ChunkSectionPos; +use crate::mc_buf::{McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_core::{ChunkSectionBlockPos, ChunkSectionPos}; use packet_macros::GamePacket; +use std::io::{Read, Write}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundSectionBlocksUpdatePacket { pub section_pos: ChunkSectionPos, pub suppress_light_updates: bool, - #[var] - pub states: Vec, + pub states: Vec, +} + +#[derive(Clone, Debug)] +pub struct BlockStateWithPosition { + pub pos: ChunkSectionBlockPos, + pub state: u32, +} + +impl McBufReadable for BlockStateWithPosition { + fn read_into(buf: &mut impl Read) -> Result { + let data = u64::var_read_into(buf)?; + let position_part = data & 4095; + let state = (data >> 12) as u32; + let position = ChunkSectionBlockPos { + x: (position_part >> 8 & 15) as u8, + y: (position_part >> 0 & 15) as u8, + z: (position_part >> 4 & 15) as u8, + }; + Ok(BlockStateWithPosition { + pos: position, + state: state, + }) + } +} + +impl McBufWritable for BlockStateWithPosition { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let data = (self.state as u64) << 12 + | ((self.pos.x as u64) << 8 | (self.pos.z as u64) << 4 | (self.pos.y as u64)); + u64::var_write_into(&data, buf); + Ok(()) + } } From 3f77390e2671045ed3ea45f24a9ade151eafe700 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 19:40:00 -0500 Subject: [PATCH 25/29] ClientboundGameEventPacket --- azalea-client/src/connect.rs | 3 +++ .../game/clientbound_game_event_packet.rs | 23 +++++++++++++++++++ azalea-protocol/src/packets/game/mod.rs | 2 ++ 3 files changed, 28 insertions(+) create mode 100644 azalea-protocol/src/packets/game/clientbound_game_event_packet.rs diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 7f245746..d7788593 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -378,6 +378,9 @@ impl Client { println!("Got section blocks update packet {:?}", p); // TODO: update world } + GamePacket::ClientboundGameEventPacket(p) => { + println!("Got game event packet {:?}", p); + } _ => panic!("Unexpected packet {:?}", packet), } } diff --git a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs new file mode 100644 index 00000000..c3ae2299 --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs @@ -0,0 +1,23 @@ +use packet_macros::{GamePacket, McBufReadable, McBufWritable}; + +#[derive(Clone, Debug, GamePacket)] +pub struct ClientboundGameEventPacket { + pub event: EventType, + pub param: f32, +} + +#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +pub enum EventType { + NoRespawnBlockAvailable = 0, + StartRaining = 1, + StopRaining = 2, + ChangeGameMode = 3, + WinGame = 4, + DemoEvent = 5, + ArrowHitPlayer = 6, + RainLevelChange = 7, + ThunderLevelChange = 8, + PufferFishSting = 9, + GuardianElderEffect = 10, + ImmediateRespawn = 11, +} diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index 66c55cd2..f8ead9d6 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -11,6 +11,7 @@ pub mod clientbound_declare_commands_packet; pub mod clientbound_disconnect_packet; pub mod clientbound_entity_event_packet; pub mod clientbound_entity_velocity_packet; +pub mod clientbound_game_event_packet; pub mod clientbound_initialize_border_packet; pub mod clientbound_keep_alive_packet; pub mod clientbound_level_chunk_with_light_packet; @@ -66,6 +67,7 @@ declare_state_packets!( 0x1a: clientbound_disconnect_packet::ClientboundDisconnectPacket, 0x1b: clientbound_entity_event_packet::ClientboundEntityEventPacket, 0x18: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, + 0x1e: clientbound_game_event_packet::ClientboundGameEventPacket, 0x20: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket, 0x21: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, 0x22: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, From 93730a550aed964d122bc08f5353e8eb0c5c9f31 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 19:55:33 -0500 Subject: [PATCH 26/29] start adding ClientboundLevelParticlesPacket --- azalea-protocol/packet-macros/src/lib.rs | 13 ++++++++ azalea-protocol/src/mc_buf/definitions.rs | 33 +++++++++++-------- azalea-protocol/src/mc_buf/mod.rs | 4 +-- .../game/clientbound_animate_packet.rs | 4 +-- .../packets/game/clientbound_chat_packet.rs | 4 +-- .../game/clientbound_game_event_packet.rs | 4 +-- ...ientbound_level_chunk_with_light_packet.rs | 6 ++-- .../clientbound_level_particles_packet.rs | 17 ++++++++++ .../game/clientbound_light_update_packet.rs | 4 +-- .../game/clientbound_player_info_packet.rs | 14 ++++---- .../packets/game/clientbound_recipe_packet.rs | 4 +-- ...lientbound_section_blocks_update_packet.rs | 2 +- .../packets/game/clientbound_sound_packet.rs | 4 +-- .../clientbound_update_advancements_packet.rs | 12 +++---- .../clientbound_update_attributes_packet.rs | 6 ++-- .../game/clientbound_update_recipes_packet.rs | 12 +++---- azalea-protocol/src/packets/game/mod.rs | 8 +++-- azalea-protocol/src/packets/mod.rs | 2 +- 18 files changed, 95 insertions(+), 58 deletions(-) create mode 100644 azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs diff --git a/azalea-protocol/packet-macros/src/lib.rs b/azalea-protocol/packet-macros/src/lib.rs index 87b216c0..59fb91eb 100755 --- a/azalea-protocol/packet-macros/src/lib.rs +++ b/azalea-protocol/packet-macros/src/lib.rs @@ -157,6 +157,19 @@ pub fn derive_mcbufwritable(input: TokenStream) -> TokenStream { create_impl_mcbufwritable(&ident, &data).into() } +#[proc_macro_derive(McBuf, attributes(var))] +pub fn derive_mcbuf(input: TokenStream) -> TokenStream { + let DeriveInput { ident, data, .. } = parse_macro_input!(input); + + let writable = create_impl_mcbufwritable(&ident, &data); + let readable = create_impl_mcbufreadable(&ident, &data); + quote! { + #writable + #readable + } + .into() +} + fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> TokenStream { let DeriveInput { ident, data, .. } = parse_macro_input!(input); diff --git a/azalea-protocol/src/mc_buf/definitions.rs b/azalea-protocol/src/mc_buf/definitions.rs index a59fc574..3867b3fc 100644 --- a/azalea-protocol/src/mc_buf/definitions.rs +++ b/azalea-protocol/src/mc_buf/definitions.rs @@ -1,8 +1,9 @@ use crate::mc_buf::read::{McBufReadable, Readable}; use crate::mc_buf::write::{McBufWritable, Writable}; +use crate::mc_buf::McBufVarReadable; use azalea_chat::component::Component; use azalea_core::{BlockPos, Direction, Slot}; -use packet_macros::{McBufReadable, McBufWritable}; +use packet_macros::McBuf; use std::io::{Read, Write}; use std::ops::Deref; use uuid::Uuid; @@ -32,7 +33,7 @@ impl From<&str> for UnsizedByteArray { } /// Represents Java's BitSet, a list of bits. -#[derive(Debug, Clone, PartialEq, Eq, Hash, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, McBuf)] pub struct BitSet { data: Vec, } @@ -159,7 +160,7 @@ impl McBufWritable for EntityDataValue { } } -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum Pose { Standing = 0, FallFlying = 1, @@ -171,7 +172,7 @@ pub enum Pose { Dying = 7, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct VillagerData { #[var] type_: u32, @@ -181,7 +182,7 @@ pub struct VillagerData { level: u32, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct Particle { #[var] pub id: i32, @@ -280,12 +281,12 @@ pub enum ParticleData { Scrape, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct BlockParticle { #[var] pub block_state: i32, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct DustParticle { /// Red value, 0-1 pub red: f32, @@ -297,7 +298,7 @@ pub struct DustParticle { pub scale: f32, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct DustColorTransitionParticle { /// Red value, 0-1 pub from_red: f32, @@ -315,12 +316,12 @@ pub struct DustColorTransitionParticle { pub to_blue: f32, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct ItemParticle { pub item: Slot, } -#[derive(Debug, Clone, McBufReadable, McBufWritable)] +#[derive(Debug, Clone, McBuf)] pub struct VibrationParticle { pub origin: BlockPos, pub position_type: String, @@ -331,9 +332,8 @@ pub struct VibrationParticle { pub ticks: u32, } -impl McBufReadable for ParticleData { - fn read_into(buf: &mut impl Read) -> Result { - let id = buf.read_varint()?; +impl ParticleData { + pub fn read_from_particle_id(buf: &mut impl Read, id: u32) -> Result { Ok(match id { 0 => ParticleData::AmbientEntityEffect, 1 => ParticleData::AngryVillager, @@ -428,6 +428,13 @@ impl McBufReadable for ParticleData { } } +impl McBufReadable for ParticleData { + fn read_into(buf: &mut impl Read) -> Result { + let id = u32::var_read_into(buf)?; + ParticleData::read_from_particle_id(buf, id) + } +} + impl McBufWritable for ParticleData { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { todo!() diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs index 94e4af0b..548ba7c2 100644 --- a/azalea-protocol/src/mc_buf/mod.rs +++ b/azalea-protocol/src/mc_buf/mod.rs @@ -4,10 +4,8 @@ mod definitions; mod read; mod write; -pub use definitions::{BitSet, EntityMetadata, UnsizedByteArray}; -use packet_macros::{McBufReadable, McBufWritable}; +pub use definitions::{BitSet, EntityMetadata, ParticleData, UnsizedByteArray}; pub use read::{read_varint_async, McBufReadable, McBufVarReadable, Readable}; -use std::ops::Deref; pub use write::{McBufVarWritable, McBufWritable, Writable}; // const DEFAULT_NBT_QUOTA: u32 = 2097152; diff --git a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs b/azalea-protocol/src/packets/game/clientbound_animate_packet.rs index 84a20381..6ac4bd99 100644 --- a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_animate_packet.rs @@ -1,4 +1,4 @@ -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundAnimatePacket { @@ -9,7 +9,7 @@ pub struct ClientboundAnimatePacket { // minecraft actually uses a u8 for this, but a varint still works and makes it // so i don't have to add a special handler -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum AnimationAction { SwingMainHand = 0, Hurt = 1, diff --git a/azalea-protocol/src/packets/game/clientbound_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_chat_packet.rs index 3786993a..7a52337e 100644 --- a/azalea-protocol/src/packets/game/clientbound_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_chat_packet.rs @@ -1,5 +1,5 @@ use azalea_chat::component::Component; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use uuid::Uuid; #[derive(Clone, Debug, GamePacket)] @@ -9,7 +9,7 @@ pub struct ClientboundChatPacket { pub sender: Uuid, } -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum ChatType { Chat = 0, System = 1, diff --git a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs index c3ae2299..faba0a6e 100644 --- a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs @@ -1,4 +1,4 @@ -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundGameEventPacket { @@ -6,7 +6,7 @@ pub struct ClientboundGameEventPacket { pub param: f32, } -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum EventType { NoRespawnBlockAvailable = 0, StartRaining = 1, diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index edcb5777..dab36050 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -1,4 +1,4 @@ -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use super::clientbound_light_update_packet::ClientboundLightUpdatePacketData; @@ -10,7 +10,7 @@ pub struct ClientboundLevelChunkWithLightPacket { pub light_data: ClientboundLightUpdatePacketData, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct ClientboundLevelChunkPacketData { pub heightmaps: azalea_nbt::Tag, // we can't parse the data in azalea-protocol because it dependso on context from other packets @@ -18,7 +18,7 @@ pub struct ClientboundLevelChunkPacketData { pub block_entities: Vec, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct BlockEntity { pub packed_xz: u8, pub y: u16, diff --git a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs new file mode 100644 index 00000000..0194d08d --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs @@ -0,0 +1,17 @@ +use crate::mc_buf::ParticleData; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, GamePacket)] +pub struct ClientboundLevelParticlesPacket { + pub particle_id: u32, + pub override_limiter: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub x_dist: f32, + pub y_dist: f32, + pub z_dist: f32, + pub max_speed: f32, + pub count: i32, + pub data: ParticleData, +} diff --git a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs index e83d1e87..0c75b356 100644 --- a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs @@ -1,5 +1,5 @@ use crate::mc_buf::BitSet; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundLightUpdatePacket { @@ -8,7 +8,7 @@ pub struct ClientboundLightUpdatePacket { pub light_data: ClientboundLightUpdatePacketData, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct ClientboundLightUpdatePacketData { trust_edges: bool, sky_y_mask: BitSet, diff --git a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs index 8e7ce4fd..db306ade 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs @@ -1,6 +1,6 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_chat::component::Component; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; use uuid::Uuid; @@ -18,14 +18,14 @@ pub enum Action { RemovePlayer(Vec), } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct PlayerProperty { name: String, value: String, signature: Option, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct AddPlayer { uuid: Uuid, name: String, @@ -37,26 +37,26 @@ pub struct AddPlayer { display_name: Option, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct UpdateGameMode { uuid: Uuid, #[var] gamemode: u32, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct UpdateLatency { uuid: Uuid, #[var] ping: i32, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct UpdateDisplayName { uuid: Uuid, display_name: Option, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct RemovePlayer { uuid: Uuid, } diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs index fa0d58f0..9a9623ad 100644 --- a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs @@ -1,6 +1,6 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; #[derive(Clone, Debug, GamePacket)] @@ -11,7 +11,7 @@ pub struct ClientboundRecipePacket { pub to_highlight: Vec, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct RecipeBookSettings { pub gui_open: bool, pub filtering_craftable: bool, diff --git a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs index 7f57a126..91d579a8 100644 --- a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs @@ -37,7 +37,7 @@ impl McBufWritable for BlockStateWithPosition { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let data = (self.state as u64) << 12 | ((self.pos.x as u64) << 8 | (self.pos.z as u64) << 4 | (self.pos.y as u64)); - u64::var_write_into(&data, buf); + u64::var_write_into(&data, buf)?; Ok(()) } } diff --git a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs b/azalea-protocol/src/packets/game/clientbound_sound_packet.rs index 67e832fe..8094227b 100644 --- a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_sound_packet.rs @@ -1,4 +1,4 @@ -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundSoundPacket { @@ -13,7 +13,7 @@ pub struct ClientboundSoundPacket { pub pitch: f32, } -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum SoundSource { Master = 0, Music = 1, diff --git a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs index fe2c226d..0bd18319 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs @@ -1,7 +1,7 @@ use crate::packets::{McBufReadable, McBufWritable}; use azalea_chat::component::Component; use azalea_core::{resource_location::ResourceLocation, Slot}; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use std::{ collections::HashMap, io::{Read, Write}, @@ -15,7 +15,7 @@ pub struct ClientboundUpdateAdvancementsPacket { pub progress: HashMap, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct Advancement { parent_id: Option, display: Option, @@ -25,7 +25,7 @@ pub struct Advancement { // requirements_strategy: RequirementsStrategy.AND } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct DisplayInfo { pub title: Component, pub description: Component, @@ -71,7 +71,7 @@ impl McBufWritable for DisplayFlags { } } -#[derive(Clone, Debug, Copy, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, Copy, McBuf)] pub enum FrameType { Task = 0, Challenge = 1, @@ -79,12 +79,12 @@ pub enum FrameType { } // nothing is written here -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct Criterion {} pub type AdvancementProgress = HashMap; -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct CriterionProgress { date: Option, } diff --git a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs index 3d83e6fb..2b382c9f 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs @@ -1,6 +1,6 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; use uuid::Uuid; @@ -11,14 +11,14 @@ pub struct ClientboundUpdateAttributesPacket { pub attributes: Vec, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct AttributeSnapshot { pub attribute: ResourceLocation, pub base: f64, pub modifiers: Vec, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct Modifier { pub uuid: Uuid, pub amount: f64, diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs index 5b4c5cd9..e7756248 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs @@ -1,7 +1,7 @@ use std::io::{Read, Write}; use azalea_core::{resource_location::ResourceLocation, Slot}; -use packet_macros::{GamePacket, McBufReadable, McBufWritable}; +use packet_macros::{GamePacket, McBuf}; use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; @@ -16,7 +16,7 @@ pub struct Recipe { pub data: RecipeData, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct ShapelessRecipe { /// Used to group similar recipes together in the recipe book. /// Tag is present in recipe JSON @@ -68,7 +68,7 @@ impl McBufReadable for ShapedRecipe { } } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct CookingRecipe { group: String, ingredient: Ingredient, @@ -77,13 +77,13 @@ pub struct CookingRecipe { #[var] cooking_time: u32, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct StoneCuttingRecipe { group: String, ingredient: Ingredient, result: Slot, } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct SmithingRecipe { base: Ingredient, addition: Ingredient, @@ -116,7 +116,7 @@ pub enum RecipeData { Smithing(SmithingRecipe), } -#[derive(Clone, Debug, McBufReadable, McBufWritable)] +#[derive(Clone, Debug, McBuf)] pub struct Ingredient { pub allowed: Vec, } diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index f8ead9d6..883e03aa 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -16,6 +16,7 @@ pub mod clientbound_initialize_border_packet; pub mod clientbound_keep_alive_packet; pub mod clientbound_level_chunk_with_light_packet; pub mod clientbound_level_event_packet; +pub mod clientbound_level_particles_packet; pub mod clientbound_light_update_packet; pub mod clientbound_login_packet; pub mod clientbound_move_entity_pos_packet; @@ -58,10 +59,10 @@ declare_state_packets!( 0x00: clientbound_add_entity_packet::ClientboundAddEntityPacket, 0x02: clientbound_add_mob_packet::ClientboundAddMobPacket, 0x04: clientbound_add_player_packet::ClientboundAddPlayerPacket, - 0x6: clientbound_animate_packet::ClientboundAnimatePacket, - 0xc: clientbound_block_update_packet::ClientboundBlockUpdatePacket, + 0x06: clientbound_animate_packet::ClientboundAnimatePacket, + 0x0c: clientbound_block_update_packet::ClientboundBlockUpdatePacket, 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, - 0xf: clientbound_chat_packet::ClientboundChatPacket, + 0x0f: clientbound_chat_packet::ClientboundChatPacket, 0x12: clientbound_declare_commands_packet::ClientboundDeclareCommandsPacket, 0x14: clientbound_container_set_content_packet::ClientboundContainerSetContentPacket, 0x1a: clientbound_disconnect_packet::ClientboundDisconnectPacket, @@ -72,6 +73,7 @@ declare_state_packets!( 0x21: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, 0x22: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, 0x23: clientbound_level_event_packet::ClientboundLevelEventPacket, + 0x24: clientbound_level_particles_packet::ClientboundLevelParticlesPacket, 0x25: clientbound_light_update_packet::ClientboundLightUpdatePacket, 0x26: clientbound_login_packet::ClientboundLoginPacket, 0x29: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket, diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs index a706646d..16e97068 100755 --- a/azalea-protocol/src/packets/mod.rs +++ b/azalea-protocol/src/packets/mod.rs @@ -43,7 +43,7 @@ where fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } -impl McBufReadable for ConnectionProtocol { +impl crate::mc_buf::McBufReadable for ConnectionProtocol { fn read_into(buf: &mut impl Read) -> Result { ConnectionProtocol::from_i32(buf.read_varint()?) .ok_or_else(|| "Invalid intention".to_string()) From f0792f25bbbf4ab038b4c1a0cdb4294f3580b16c Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 20:03:24 -0500 Subject: [PATCH 27/29] add derive McBuf to every packet --- azalea-protocol/packet-macros/src/lib.rs | 8 ++------ .../src/packets/game/clientbound_add_entity_packet.rs | 4 ++-- .../src/packets/game/clientbound_add_mob_packet.rs | 4 ++-- .../src/packets/game/clientbound_add_player_packet.rs | 4 ++-- .../src/packets/game/clientbound_animate_packet.rs | 2 +- .../src/packets/game/clientbound_block_update_packet.rs | 4 ++-- .../packets/game/clientbound_change_difficulty_packet.rs | 4 ++-- .../src/packets/game/clientbound_chat_packet.rs | 2 +- .../game/clientbound_container_set_content_packet.rs | 4 ++-- .../src/packets/game/clientbound_custom_payload_packet.rs | 4 ++-- .../src/packets/game/clientbound_disconnect_packet.rs | 4 ++-- .../src/packets/game/clientbound_entity_event_packet.rs | 4 ++-- .../packets/game/clientbound_entity_velocity_packet.rs | 4 ++-- .../src/packets/game/clientbound_game_event_packet.rs | 2 +- .../packets/game/clientbound_initialize_border_packet.rs | 4 ++-- .../src/packets/game/clientbound_keep_alive_packet.rs | 4 ++-- .../game/clientbound_level_chunk_with_light_packet.rs | 2 +- .../src/packets/game/clientbound_level_event_packet.rs | 4 ++-- .../packets/game/clientbound_level_particles_packet.rs | 4 ++-- .../src/packets/game/clientbound_light_update_packet.rs | 2 +- .../src/packets/game/clientbound_login_packet.rs | 4 ++-- .../packets/game/clientbound_move_entity_pos_packet.rs | 4 ++-- .../packets/game/clientbound_move_entity_posrot_packet.rs | 4 ++-- .../packets/game/clientbound_move_entity_rot_packet.rs | 4 ++-- .../packets/game/clientbound_player_abilities_packet.rs | 4 ++-- .../src/packets/game/clientbound_player_info_packet.rs | 2 +- .../packets/game/clientbound_player_position_packet.rs | 4 ++-- .../src/packets/game/clientbound_recipe_packet.rs | 2 +- .../packets/game/clientbound_remove_entities_packet.rs | 4 ++-- .../src/packets/game/clientbound_rotate_head_packet.rs | 4 ++-- .../game/clientbound_section_blocks_update_packet.rs | 4 ++-- .../packets/game/clientbound_set_carried_item_packet.rs | 4 ++-- .../packets/game/clientbound_set_chunk_cache_center.rs | 4 ++-- .../game/clientbound_set_default_spawn_position_packet.rs | 4 ++-- .../packets/game/clientbound_set_entity_data_packet.rs | 4 ++-- .../packets/game/clientbound_set_entity_link_packet.rs | 4 ++-- .../src/packets/game/clientbound_set_experience_packet.rs | 4 ++-- .../src/packets/game/clientbound_set_health_packet.rs | 4 ++-- .../src/packets/game/clientbound_set_time_packet.rs | 4 ++-- .../src/packets/game/clientbound_sound_packet.rs | 2 +- .../packets/game/clientbound_teleport_entity_packet.rs | 4 ++-- .../game/clientbound_update_advancements_packet.rs | 2 +- .../packets/game/clientbound_update_attributes_packet.rs | 2 +- .../src/packets/game/clientbound_update_recipes_packet.rs | 2 +- .../src/packets/game/clientbound_update_tags_packet.rs | 4 ++-- .../game/clientbound_update_view_distance_packet.rs | 4 ++-- .../src/packets/game/serverbound_custom_payload_packet.rs | 4 ++-- .../src/packets/game/serverbound_keep_alive_packet.rs | 4 ++-- .../src/packets/handshake/client_intention_packet.rs | 4 ++-- .../src/packets/login/clientbound_custom_query_packet.rs | 4 ++-- .../packets/login/clientbound_login_disconnect_packet.rs | 4 ++-- .../src/packets/login/serverbound_hello_packet.rs | 4 ++-- .../src/packets/login/serverbound_key_packet.rs | 4 ++-- .../packets/status/serverbound_status_request_packet.rs | 4 ++-- code-generator/packetcodegen.py | 4 ++-- 55 files changed, 99 insertions(+), 103 deletions(-) diff --git a/azalea-protocol/packet-macros/src/lib.rs b/azalea-protocol/packet-macros/src/lib.rs index 59fb91eb..f3fe4e40 100755 --- a/azalea-protocol/packet-macros/src/lib.rs +++ b/azalea-protocol/packet-macros/src/lib.rs @@ -182,8 +182,8 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke _ => panic!("#[derive(*Packet)] can only be used on structs with named fields"), }; - let mcbufreadable_impl = create_impl_mcbufreadable(&ident, &data); - let mcbufwritable_impl = create_impl_mcbufwritable(&ident, &data); + let _mcbufreadable_impl = create_impl_mcbufreadable(&ident, &data); + let _mcbufwritable_impl = create_impl_mcbufwritable(&ident, &data); let contents = quote! { impl #ident { @@ -202,10 +202,6 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke Ok(Self::read_into(buf)?.get()) } } - - #mcbufreadable_impl - - #mcbufwritable_impl }; contents.into() diff --git a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs index 55fbd2e1..9afd151b 100644 --- a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundAddEntityPacket { #[var] pub id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_add_mob_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_mob_packet.rs index ab72eb59..bc0ddcef 100644 --- a/azalea-protocol/src/packets/game/clientbound_add_mob_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_add_mob_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundAddMobPacket { #[var] pub id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs index 8f848c99..f1947d09 100644 --- a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundAddPlayerPacket { #[var] pub id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs b/azalea-protocol/src/packets/game/clientbound_animate_packet.rs index 6ac4bd99..0bba1a25 100644 --- a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_animate_packet.rs @@ -1,6 +1,6 @@ use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundAnimatePacket { #[var] pub id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs index 575b7f46..f068cc7d 100644 --- a/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs @@ -1,7 +1,7 @@ use azalea_core::BlockPos; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundBlockUpdatePacket { pub pos: BlockPos, // TODO: in vanilla this is a BlockState, but here we just have it as a number. diff --git a/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs b/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs index e12cfff3..edda52d9 100755 --- a/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs @@ -1,7 +1,7 @@ use azalea_core::difficulty::Difficulty; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundChangeDifficultyPacket { pub difficulty: Difficulty, pub locked: bool, diff --git a/azalea-protocol/src/packets/game/clientbound_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_chat_packet.rs index 7a52337e..77c5370c 100644 --- a/azalea-protocol/src/packets/game/clientbound_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_chat_packet.rs @@ -2,7 +2,7 @@ use azalea_chat::component::Component; use packet_macros::{GamePacket, McBuf}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundChatPacket { pub message: Component, pub type_: ChatType, diff --git a/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs b/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs index aea09e09..d38bbfda 100644 --- a/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs @@ -1,7 +1,7 @@ use azalea_core::Slot; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundContainerSetContentPacket { pub container_id: u8, #[var] diff --git a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs index 2c56ea2b..b9ccbba4 100755 --- a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs @@ -1,8 +1,8 @@ use crate::mc_buf::UnsizedByteArray; use azalea_core::resource_location::ResourceLocation; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundCustomPayloadPacket { pub identifier: ResourceLocation, pub data: UnsizedByteArray, diff --git a/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs b/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs index 2e72b19b..c030d512 100644 --- a/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs @@ -1,7 +1,7 @@ use azalea_chat::component::Component; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundDisconnectPacket { pub reason: Component, } diff --git a/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs index 55e4d419..1b06bff7 100644 --- a/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; // we can't identify the status in azalea-protocol since they vary depending on the entity -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundEntityEventPacket { pub entity_id: i32, pub entity_status: i8, diff --git a/azalea-protocol/src/packets/game/clientbound_entity_velocity_packet.rs b/azalea-protocol/src/packets/game/clientbound_entity_velocity_packet.rs index 4fc8f86f..07218c4e 100644 --- a/azalea-protocol/src/packets/game/clientbound_entity_velocity_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_entity_velocity_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundEntityVelocityPacket { #[var] pub entity_id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs index faba0a6e..dd5f08f6 100644 --- a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs @@ -1,6 +1,6 @@ use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundGameEventPacket { pub event: EventType, pub param: f32, diff --git a/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs b/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs index 435e43cc..a522eba3 100644 --- a/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundInitializeBorderPacket { pub new_center_x: f64, pub new_center_z: f64, diff --git a/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs b/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs index d5dab9a9..18628c86 100644 --- a/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundKeepAlivePacket { pub id: u64, } diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs index dab36050..43bda0b6 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs @@ -2,7 +2,7 @@ use packet_macros::{GamePacket, McBuf}; use super::clientbound_light_update_packet::ClientboundLightUpdatePacketData; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundLevelChunkWithLightPacket { pub x: i32, pub z: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs index b8572a85..70926268 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs @@ -1,7 +1,7 @@ use azalea_core::BlockPos; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundLevelEventPacket { pub type_: i32, pub pos: BlockPos, diff --git a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs index 0194d08d..43c3b31a 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs @@ -1,7 +1,7 @@ use crate::mc_buf::ParticleData; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundLevelParticlesPacket { pub particle_id: u32, pub override_limiter: bool, diff --git a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs index 0c75b356..f04987ac 100644 --- a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs @@ -1,7 +1,7 @@ use crate::mc_buf::BitSet; use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundLightUpdatePacket { pub x: i32, pub z: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_login_packet.rs b/azalea-protocol/src/packets/game/clientbound_login_packet.rs index 9c8b7df1..b4a1b8d4 100755 --- a/azalea-protocol/src/packets/game/clientbound_login_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_login_packet.rs @@ -1,7 +1,7 @@ use azalea_core::{game_type::GameType, resource_location::ResourceLocation}; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundLoginPacket { pub player_id: u32, pub hardcore: bool, diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs index c9aff7cb..0fc0104a 100644 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundMoveEntityPosPacket { #[var] pub entity_id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs index 645912e7..5fde1b93 100644 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundMoveEntityPosRotPacket { #[var] pub entity_id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs index 6ce0faa9..c8d0170b 100644 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundMoveEntityRotPacket { #[var] pub entity_id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs index ed27ecf3..c3387f7f 100755 --- a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs @@ -1,8 +1,8 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable}; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundPlayerAbilitiesPacket { pub flags: PlayerAbilitiesFlags, pub flying_speed: f32, diff --git a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs index db306ade..cb17f1f5 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_info_packet.rs @@ -4,7 +4,7 @@ use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundPlayerInfoPacket { pub action: Action, } diff --git a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs index 796d8334..0457269a 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs @@ -1,8 +1,8 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable}; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundPlayerPositionPacket { pub x: f64, pub y: f64, diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs index 9a9623ad..e76504cc 100644 --- a/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_recipe_packet.rs @@ -3,7 +3,7 @@ use azalea_core::resource_location::ResourceLocation; use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundRecipePacket { pub action: State, pub settings: RecipeBookSettings, diff --git a/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs b/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs index 265d0c64..8f51596d 100644 --- a/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundRemoveEntitiesPacket { #[var] pub entity_ids: Vec, diff --git a/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs b/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs index d423885d..71b485ae 100644 --- a/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundRotateHeadPacket { #[var] pub entity_id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs index 91d579a8..6c429edb 100644 --- a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs @@ -1,9 +1,9 @@ use crate::mc_buf::{McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; use azalea_core::{ChunkSectionBlockPos, ChunkSectionPos}; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSectionBlocksUpdatePacket { pub section_pos: ChunkSectionPos, pub suppress_light_updates: bool, diff --git a/azalea-protocol/src/packets/game/clientbound_set_carried_item_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_carried_item_packet.rs index 4f0bf575..003b6ccc 100755 --- a/azalea-protocol/src/packets/game/clientbound_set_carried_item_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_carried_item_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; /// Sent to change the player's slot selection. -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetCarriedItemPacket { pub slot: u8, } diff --git a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs index 60f2ab94..7557c16b 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetChunkCacheCenterPacket { #[var] pub x: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs index dad050cc..7ac42c5c 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs @@ -1,7 +1,7 @@ use azalea_core::BlockPos; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetDefaultSpawnPositionPacket { pub pos: BlockPos, pub angle: f32, diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs index 752b7e6a..8a568689 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs @@ -1,7 +1,7 @@ use crate::mc_buf::EntityMetadata; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetEntityDataPacket { #[var] pub id: i32, diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs index 7ee4a43c..e6e3af67 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetEntityLinkPacket { pub source_id: u32, pub dest_id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs index 88c306dc..bcb6393d 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetExperiencePacket { pub experience_progress: f32, #[var] diff --git a/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs index 136ef475..6c75cf63 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetHealthPacket { pub health: f32, #[var] diff --git a/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs index 02bf88d7..4cad0693 100644 --- a/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSetTimePacket { pub game_time: u64, pub day_time: u64, diff --git a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs b/azalea-protocol/src/packets/game/clientbound_sound_packet.rs index 8094227b..797f03de 100644 --- a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_sound_packet.rs @@ -1,6 +1,6 @@ use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSoundPacket { #[var] /// TODO: use the sound registry instead of just being a u32 diff --git a/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs index ea8788d6..c10db7b9 100644 --- a/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundTeleportEntityPacket { #[var] pub id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs index 0bd18319..daa1ac93 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs @@ -7,7 +7,7 @@ use std::{ io::{Read, Write}, }; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundUpdateAdvancementsPacket { pub reset: bool, pub added: HashMap, diff --git a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs index 2b382c9f..d0e7c9ee 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs @@ -4,7 +4,7 @@ use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; use uuid::Uuid; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundUpdateAttributesPacket { #[var] pub entity_id: u32, diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs index e7756248..27839919 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs @@ -5,7 +5,7 @@ use packet_macros::{GamePacket, McBuf}; use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundUpdateRecipesPacket { pub recipes: Vec, } diff --git a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs index f82a4177..60794f03 100755 --- a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs @@ -1,12 +1,12 @@ use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_core::resource_location::ResourceLocation; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; use std::{ collections::HashMap, io::{Read, Write}, }; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundUpdateTagsPacket { pub tags: HashMap>, } diff --git a/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs index fe65d048..8288bd73 100755 --- a/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundUpdateViewDistancePacket { #[var] pub view_distance: i32, diff --git a/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs b/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs index eefafdd1..bef25b59 100644 --- a/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs +++ b/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs @@ -1,8 +1,8 @@ use crate::mc_buf::UnsizedByteArray; use azalea_core::resource_location::ResourceLocation; -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ServerboundCustomPayloadPacket { pub identifier: ResourceLocation, pub data: UnsizedByteArray, diff --git a/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs b/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs index 740b18e3..c430499e 100644 --- a/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs +++ b/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs @@ -1,6 +1,6 @@ -use packet_macros::GamePacket; +use packet_macros::{GamePacket, McBuf}; -#[derive(Clone, Debug, GamePacket)] +#[derive(Clone, Debug, McBuf, GamePacket)] pub struct ServerboundKeepAlivePacket { pub id: u64, } diff --git a/azalea-protocol/src/packets/handshake/client_intention_packet.rs b/azalea-protocol/src/packets/handshake/client_intention_packet.rs index 98caf34c..410c11ab 100755 --- a/azalea-protocol/src/packets/handshake/client_intention_packet.rs +++ b/azalea-protocol/src/packets/handshake/client_intention_packet.rs @@ -1,8 +1,8 @@ use crate::packets::ConnectionProtocol; -use packet_macros::HandshakePacket; +use packet_macros::{HandshakePacket, McBuf}; use std::hash::Hash; -#[derive(Hash, Clone, Debug, HandshakePacket)] +#[derive(Hash, Clone, Debug, McBuf, HandshakePacket)] pub struct ClientIntentionPacket { #[var] pub protocol_version: u32, diff --git a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs index fc5dd1a2..1b1da87a 100755 --- a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs +++ b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs @@ -1,9 +1,9 @@ use crate::mc_buf::UnsizedByteArray; use azalea_core::resource_location::ResourceLocation; -use packet_macros::LoginPacket; +use packet_macros::{LoginPacket, McBuf}; use std::hash::Hash; -#[derive(Hash, Clone, Debug, LoginPacket)] +#[derive(Hash, Clone, Debug, McBuf, LoginPacket)] pub struct ClientboundCustomQueryPacket { #[var] pub transaction_id: u32, diff --git a/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs index 28d91c79..9ab09e3b 100644 --- a/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs +++ b/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs @@ -1,7 +1,7 @@ use azalea_chat::component::Component; -use packet_macros::LoginPacket; +use packet_macros::{LoginPacket, McBuf}; -#[derive(Clone, Debug, LoginPacket)] +#[derive(Clone, Debug, McBuf, LoginPacket)] pub struct ClientboundLoginDisconnectPacket { pub reason: Component, } diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs index eb6a4065..5cb660ed 100755 --- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs +++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::LoginPacket; +use packet_macros::{LoginPacket, McBuf}; use std::hash::Hash; -#[derive(Hash, Clone, Debug, LoginPacket)] +#[derive(Hash, Clone, Debug, McBuf, LoginPacket)] pub struct ServerboundHelloPacket { pub username: String, } diff --git a/azalea-protocol/src/packets/login/serverbound_key_packet.rs b/azalea-protocol/src/packets/login/serverbound_key_packet.rs index 2ff8dda6..9100823d 100644 --- a/azalea-protocol/src/packets/login/serverbound_key_packet.rs +++ b/azalea-protocol/src/packets/login/serverbound_key_packet.rs @@ -1,7 +1,7 @@ -use packet_macros::LoginPacket; +use packet_macros::{LoginPacket, McBuf}; use std::hash::Hash; -#[derive(Hash, Clone, Debug, LoginPacket)] +#[derive(Hash, Clone, Debug, McBuf, LoginPacket)] pub struct ServerboundKeyPacket { pub shared_secret: Vec, pub nonce: Vec, diff --git a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs index c15673d9..3369e6a9 100755 --- a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs +++ b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs @@ -1,4 +1,4 @@ -use packet_macros::StatusPacket; +use packet_macros::{McBuf, StatusPacket}; -#[derive(Clone, Debug, StatusPacket)] +#[derive(Clone, Debug, McBuf, StatusPacket)] pub struct ServerboundStatusRequestPacket {} diff --git a/code-generator/packetcodegen.py b/code-generator/packetcodegen.py index fbb38eeb..b84877e4 100644 --- a/code-generator/packetcodegen.py +++ b/code-generator/packetcodegen.py @@ -84,8 +84,8 @@ def generate(burger_packets, mappings: Mappings, target_packet_id, target_packet generated_packet_code = [] uses = set() generated_packet_code.append( - f'#[derive(Clone, Debug, {to_camel_case(state)}Packet)]') - uses.add(f'packet_macros::{to_camel_case(state)}Packet') + f'#[derive(Clone, Debug, McBuf, {to_camel_case(state)}Packet)]') + uses.add(f'packet_macros::{{to_camel_case(state)}Packet, McBuf}') obfuscated_class_name = packet['class'].split('.')[0].split('$')[0] class_name = mappings.get_class( From 9fc71ab2d1e669fb3533f3012921b1e8dbacd257 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 20:03:52 -0500 Subject: [PATCH 28/29] fix python error --- code-generator/packetcodegen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code-generator/packetcodegen.py b/code-generator/packetcodegen.py index b84877e4..3d453a4e 100644 --- a/code-generator/packetcodegen.py +++ b/code-generator/packetcodegen.py @@ -85,7 +85,7 @@ def generate(burger_packets, mappings: Mappings, target_packet_id, target_packet uses = set() generated_packet_code.append( f'#[derive(Clone, Debug, McBuf, {to_camel_case(state)}Packet)]') - uses.add(f'packet_macros::{{to_camel_case(state)}Packet, McBuf}') + uses.add(f'packet_macros::{{{to_camel_case(state)}Packet, McBuf}}') obfuscated_class_name = packet['class'].split('.')[0].split('$')[0] class_name = mappings.get_class( From c16e958d0be671a17edf060aee9850faccbcfe14 Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 14 May 2022 20:43:25 -0500 Subject: [PATCH 29/29] ClientboundLevelParticlesPacket works --- azalea-client/src/connect.rs | 3 ++ .../clientbound_level_particles_packet.rs | 45 +++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index d7788593..b8b6e372 100755 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -381,6 +381,9 @@ impl Client { GamePacket::ClientboundGameEventPacket(p) => { println!("Got game event packet {:?}", p); } + GamePacket::ClientboundLevelParticlesPacket(p) => { + println!("Got level particles packet {:?}", p); + } _ => panic!("Unexpected packet {:?}", packet), } } diff --git a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs index 43c3b31a..a3538598 100644 --- a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs @@ -1,7 +1,9 @@ -use crate::mc_buf::ParticleData; -use packet_macros::{GamePacket, McBuf}; +use std::io::{Read, Write}; -#[derive(Clone, Debug, McBuf, GamePacket)] +use crate::mc_buf::{McBufReadable, McBufWritable, ParticleData}; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, GamePacket)] pub struct ClientboundLevelParticlesPacket { pub particle_id: u32, pub override_limiter: bool, @@ -15,3 +17,40 @@ pub struct ClientboundLevelParticlesPacket { pub count: i32, pub data: ParticleData, } + +impl McBufReadable for ClientboundLevelParticlesPacket { + fn read_into(buf: &mut impl Read) -> Result { + let particle_id = u32::read_into(buf)?; + let override_limiter = bool::read_into(buf)?; + let x = f64::read_into(buf)?; + let y = f64::read_into(buf)?; + let z = f64::read_into(buf)?; + let x_dist = f32::read_into(buf)?; + let y_dist = f32::read_into(buf)?; + let z_dist = f32::read_into(buf)?; + let max_speed = f32::read_into(buf)?; + let count = i32::read_into(buf)?; + + let data = ParticleData::read_from_particle_id(buf, particle_id)?; + + Ok(Self { + particle_id, + override_limiter, + x, + y, + z, + x_dist, + y_dist, + z_dist, + max_speed, + count, + data, + }) + } +} + +impl McBufWritable for ClientboundLevelParticlesPacket { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + todo!(); + } +}