diff --git a/src/main.rs b/src/main.rs index 678c2cb..1e7f6ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,12 +74,12 @@ async fn main() -> Result<()> { let world = read_world(&args.map_dir)?; info!("Done."); + let state = Arc::new(state::State::new(VERSION, VERSION_NUM, args)); + info!("Generating world chunk packets"); - let world_cache = WorldCache::from(world); + let world_cache = WorldCache::from_anvil(state.clone(), world); info!("Done."); - let state = Arc::new(state::State::new(VERSION, VERSION_NUM, args)); - #[cfg(feature = "lan")] net::spawn_lan_broadcast(state.clone()).await?; diff --git a/src/net/cache.rs b/src/net/cache.rs index 34fa11d..c539618 100644 --- a/src/net/cache.rs +++ b/src/net/cache.rs @@ -17,7 +17,7 @@ * . */ -use std::cmp::Ordering; +use std::{cmp::Ordering, sync::Arc}; use rayon::prelude::*; @@ -31,6 +31,7 @@ use crate::{ Encoder, }, world::{blocks::Blocks, World}, + CrawlState, }; #[derive(Debug)] @@ -38,8 +39,8 @@ pub struct WorldCache { pub encoded: Vec>, } -impl From for WorldCache { - fn from(world: World) -> Self { +impl WorldCache { + pub fn from_anvil(crawlstate: CrawlState, world: World) -> Self { let mut chunks = world.0.iter().collect::>(); chunks.sort_by(|((ax, az), _), ((bx, bz), _)| { @@ -54,7 +55,7 @@ impl From for WorldCache { let chunks = chunks .par_iter() - .map(|(_, c)| ChunkDataUpdateLightC::new(c, &block_states)) + .map(|(_, c)| ChunkDataUpdateLightC::new(crawlstate.clone(), c, &block_states)) .collect::>>(); let encoded = chunks @@ -76,6 +77,7 @@ impl From for WorldCache { pub struct RegistryCache { pub encoded: Vec, pub the_end_id: VarInt, + pub the_end_biome_id: u16, } impl From<&AllRegistries> for RegistryCache { @@ -83,6 +85,7 @@ impl From<&AllRegistries> for RegistryCache { let mut encoder = Encoder::new(); let dimensions = Registry::from(registry.dimension_type.clone()); + let biomes = Registry::from(registry.biome.clone()); encoder .append_packet(&Registry::from(registry.trim_material.clone())) .expect("Failed to encode trim material"); @@ -92,9 +95,6 @@ impl From<&AllRegistries> for RegistryCache { encoder .append_packet(&Registry::from(registry.banner_pattern.clone())) .expect("Failed to encode banner pattern"); - encoder - .append_packet(&Registry::from(registry.biome.clone())) - .expect("Failed to encode biome"); encoder .append_packet(&Registry::from(registry.chat_type.clone())) .expect("Failed to encode chat type"); @@ -104,6 +104,9 @@ impl From<&AllRegistries> for RegistryCache { encoder .append_packet(&dimensions) .expect("Failed to encode dimensions"); + encoder + .append_packet(&biomes) + .expect("Failed to encode biomes"); encoder .append_packet(&Registry::from(registry.wolf_variant.clone())) .expect("Failed to encode wolf variants"); @@ -114,6 +117,7 @@ impl From<&AllRegistries> for RegistryCache { Self { encoded: encoder.take().to_vec(), the_end_id: VarInt(dimensions.index_of("minecraft:the_end")), + the_end_biome_id: biomes.index_of("minecraft:the_end") as u16, } } } diff --git a/src/protocol/packets/play/world.rs b/src/protocol/packets/play/world.rs index 4aa1f16..97f8e48 100644 --- a/src/protocol/packets/play/world.rs +++ b/src/protocol/packets/play/world.rs @@ -17,7 +17,7 @@ * . */ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; use bit_vec::BitVec; use bytes::BufMut; @@ -32,6 +32,7 @@ use crate::{ self, blocks::{BlockState, Blocks}, }, + CrawlState, }; #[derive(Debug)] @@ -258,7 +259,11 @@ impl Encode for ChunkDataUpdateLightC<'_> { } impl ChunkSection { - pub fn anvil_to_sec(value: &world::Section, block_states: &Blocks) -> Self { + pub fn anvil_to_sec( + crawlstate: CrawlState, + value: &world::Section, + block_states: &Blocks, + ) -> Self { let mut blocks = Vec::new(); let bit_length = (64 - (value.block_states.palette.len() as u64).leading_zeros()).max(4); @@ -379,7 +384,9 @@ impl ChunkSection { }, biomes: PalettedContainer { bits_per_entry: 0, - palette: Palette::SingleValued(BlockState(0)), + palette: Palette::SingleValued(BlockState( + crawlstate.registry_cache.the_end_biome_id, + )), data_array: fastnbt::LongArray::new(vec![]), }, } @@ -387,11 +394,11 @@ impl ChunkSection { } impl ChunkDataUpdateLightC<'_> { - pub fn new(value: &world::Chunk, block_states: &Blocks) -> Self { + pub fn new(crawlstate: CrawlState, value: &world::Chunk, block_states: &Blocks) -> Self { let data = value .sections .iter() - .map(|sec| ChunkSection::anvil_to_sec(sec, block_states)) + .map(|sec| ChunkSection::anvil_to_sec(crawlstate.clone(), sec, block_states)) .collect::>(); let block_entities = value