Skip to content

Commit

Permalink
Merge pull request #28 from lukas0008/master
Browse files Browse the repository at this point in the history
World Loading (woohoo)
  • Loading branch information
Snowiiii authored Aug 12, 2024
2 parents dbc7b9f + 435cd3b commit b375564
Show file tree
Hide file tree
Showing 18 changed files with 273,224 additions and 269 deletions.
309 changes: 115 additions & 194 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pumpkin-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition.workspace = true

[dependencies]
pumpkin-macros = { path = "../pumpkin-macros" }
pumpkin-world = { path = "../pumpkin-world" }
pumpkin-text = { path = "../pumpkin-text" }

bytes = "1.7"
Expand All @@ -26,3 +27,5 @@ num-derive = "0.4"
aes = "0.8.4"
cfb8 = "0.8.1"
take_mut = "0.2.2"
itertools = "0.13.0"
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
12 changes: 11 additions & 1 deletion pumpkin-protocol/src/bytebuf/packet_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ use serde::{
Deserialize, Deserializer, Serialize, Serializer,
};

use crate::{ClientPacket, ServerPacket, VarInt, VarIntType};
use crate::{BitSet, ClientPacket, ServerPacket, VarInt, VarIntType};

use super::{deserializer, serializer, ByteBuffer, DeserializerError};

impl Serialize for BitSet {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// TODO: make this right
(self.0.clone(), self.1.clone()).serialize(serializer)
}
}

impl Serialize for VarInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down
10 changes: 10 additions & 0 deletions pumpkin-protocol/src/client/play/c_center_chunk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use pumpkin_macros::packet;

use crate::VarInt;

#[derive(serde::Serialize)]
#[packet(0x54)]
pub struct CCenterChunk {
pub chunk_x: VarInt,
pub chunk_z: VarInt
}
134 changes: 134 additions & 0 deletions pumpkin-protocol/src/client/play/c_chunk_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::collections::HashMap;

use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt};
use fastnbt::LongArray;
use itertools::Itertools;
use pumpkin_macros::packet;
use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS};

#[packet(0x27)]
pub struct CChunkData<'a>(pub &'a ChunkData);

impl<'a> ClientPacket for CChunkData<'a> {
fn write(&self, buf: &mut crate::bytebuf::ByteBuffer) {
// Chunk X
buf.put_i32(self.0.position.0);
// Chunk Z
buf.put_i32(self.0.position.1);

let heightmap_nbt =
fastnbt::to_bytes_with_opts(&self.0.heightmaps, fastnbt::SerOpts::network_nbt())
.unwrap();
// Heightmaps
buf.put_slice(&heightmap_nbt);

let mut data_buf = ByteBuffer::empty();
self.0
.blocks
.iter()
.chunks(16 * 16 * 16)
.into_iter()
.for_each(|chunk| {
let chunk = chunk.collect_vec();
let block_count = chunk
.iter()
.filter(|block| ***block != 0 && ***block != 12959 && ***block != 12958)
.count() as i16;
// Block count
data_buf.put_i16(block_count);
//// Block states

let palette = chunk.clone().into_iter().dedup().collect_vec();
// TODO: make dynamic block_size work
// TODO: make direct block_size work
enum PaletteType {
Indirect(u32),
Direct,
}
let palette_type = {
let palette_bit_len = 64 - (palette.len() as i64 - 1).leading_zeros();
if palette_bit_len > 8 {
PaletteType::Direct
} else if palette_bit_len > 3 {
PaletteType::Indirect(palette_bit_len)
} else {
PaletteType::Indirect(4)
}
// TODO: fix indirect palette to work correctly
// PaletteType::Direct
};

let mut block_data_array = Vec::new();
match palette_type {
PaletteType::Indirect(block_size) => {
// Bits per entry
data_buf.put_u8(block_size as u8);
// Palette length
data_buf.put_var_int(&VarInt(palette.len() as i32));
let mut palette_map = HashMap::new();
palette.iter().enumerate().for_each(|(i, id)| {
palette_map.insert(**id, i);
// Palette
data_buf.put_var_int(&VarInt(**id as i32));
});
for block_clump in chunk.chunks(64 / block_size as usize) {
let mut out_long: i64 = 0;
for block in block_clump.iter().rev() {
let index = palette_map
.get(*block)
.expect("Its just got added, ofc it should be there");
out_long = out_long << block_size | (*index as i64);
}
block_data_array.push(out_long);
}
}
PaletteType::Direct => {
// Bits per entry
data_buf.put_u8(DIRECT_PALETTE_BITS as u8);
for block_clump in chunk.chunks(64 / DIRECT_PALETTE_BITS as usize) {
let mut out_long: i64 = 0;
for block in block_clump.iter().rev() {
out_long = out_long << DIRECT_PALETTE_BITS | (**block as i64);
}
block_data_array.push(out_long);
}
}
}

// Data array length
// TODO: precompute this and omit making the `block_data_array`
data_buf.put_var_int(&VarInt(block_data_array.len() as i32));
// Data array
for data_int in block_data_array {
data_buf.put_i64(data_int);
}

//// Biomes
// TODO: make biomes work
data_buf.put_u8(0);
data_buf.put_var_int(&VarInt(0));
data_buf.put_var_int(&VarInt(0));
});

// Size
buf.put_var_int(&VarInt(data_buf.buf().len() as i32));
// Data
buf.put_slice(&data_buf.buf());

// TODO: block entities
buf.put_var_int(&VarInt(0));

// TODO
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));

buf.put_var_int(&VarInt(0));
buf.put_var_int(&VarInt(0));
}
}
4 changes: 4 additions & 0 deletions pumpkin-protocol/src/client/play/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod c_center_chunk;
mod c_actionbar;
mod c_change_difficulty;
mod c_chunk_data;
mod c_chunk_data_update_light;
mod c_disguised_chat_message;
mod c_entity_animation;
Expand All @@ -25,8 +27,10 @@ mod c_update_entity_pos;
mod c_update_entity_rot;
mod player_action;

pub use c_center_chunk::*;
pub use c_actionbar::*;
pub use c_change_difficulty::*;
pub use c_chunk_data::*;
pub use c_chunk_data_update_light::*;
pub use c_disguised_chat_message::*;
pub use c_entity_animation::*;
Expand Down
2 changes: 1 addition & 1 deletion pumpkin-protocol/src/packet_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl PacketEncoder {
.encode(&mut writer)
.map_err(|_| PacketError::EncodeID)?;
packet.write(&mut packet_buf);

writer
.write(packet_buf.buf())
.map_err(|_| PacketError::EncodeFailedWrite)?;
Expand Down
12 changes: 9 additions & 3 deletions pumpkin-world/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ version.workspace = true
edition.workspace = true

[dependencies]
pumpkin-protocol = { path = "../pumpkin-protocol"}
fastanvil = "0.31"
# fastanvil = "0.31"
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
fastsnbt = "0.2"
tokio.workspace = true
tokio.workspace = true
itertools = "0.13.0"
thiserror = "1.0.63"
futures = "0.3.30"
flate2 = "1.0.31"
serde = { version = "1.0.205", features = ["derive"] }
lazy_static = "1.5.0"
serde_json = "1.0.122"
Loading

0 comments on commit b375564

Please sign in to comment.