From 18dc3a84d4b58a58085682cc97f1b52ffee5091c Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 3 May 2022 22:48:57 -0500 Subject: [PATCH] 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();