aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-03 22:48:57 -0500
committermat <github@matdoes.dev>2022-05-03 22:48:57 -0500
commit18dc3a84d4b58a58085682cc97f1b52ffee5091c (patch)
treed96d2cf7214398e10d7a3c96c09eae3063a46b22
parentc9878129274258a30dc3ee0ecbd064b4fcf9bc6e (diff)
downloadazalea-drasl-18dc3a84d4b58a58085682cc97f1b52ffee5091c.tar.xz
start adding bit storage
-rwxr-xr-x.gitignore3
-rw-r--r--azalea-world/src/bit_storage.rs149
-rw-r--r--azalea-world/src/lib.rs2
-rw-r--r--bot/src/main.rs2
4 files changed, 155 insertions, 1 deletions
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<u64>,
+ 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<Vec<u64>>) -> Result<Self, BitStorageError> {
+ 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();