Fix bug in chunk encoder

This commit is contained in:
Ryan 2022-05-16 11:53:21 -07:00
parent 620c0bf287
commit 8da32d0b8b
7 changed files with 60 additions and 40 deletions

View file

@ -7,8 +7,8 @@ use valence::client::GameMode;
use valence::config::{Config, ServerListPing}; use valence::config::{Config, ServerListPing};
use valence::text::Color; use valence::text::Color;
use valence::{ use valence::{
async_trait, ChunkPos, ClientMut, DimensionId, Server, ShutdownResult, Text, TextFormat, async_trait, ChunkPos, ClientMut, DimensionId, EntityType, Server, ShutdownResult, Text,
WorldId, WorldsMut, TextFormat, WorldId, WorldsMut,
}; };
pub fn main() -> ShutdownResult { pub fn main() -> ShutdownResult {
@ -83,14 +83,38 @@ impl Config for Game {
if x != -size && x != size - 1 && z != -size && z != size - 1 { if x != -size && x != size - 1 && z != -size && z != size - 1 {
for z in 0..16 { for z in 0..16 {
for x in 0..16 { for x in 0..16 {
for y in 0..50 { let block_x = pos.x * 16 + x as i32;
chunk.set_block_state(x, y, z, BlockState::STONE); let block_z = pos.z * 16 + z as i32;
let height = 50.0
+ ((block_x as f64 / 10.0).cos() + (block_z as f64 / 10.0).sin())
* 7.0;
for y in 0..height.round() as usize {
let states = [
BlockState::ACACIA_PLANKS,
BlockState::SLIME_BLOCK,
BlockState::IRON_BLOCK,
BlockState::SEA_LANTERN,
BlockState::STONE,
BlockState::DIRT,
BlockState::PRISMARINE_BRICKS,
BlockState::DIAMOND_ORE,
];
chunk.set_block_state(x, y, z, states[y % states.len()]);
} }
} }
} }
} }
} }
} }
let entity_id = world.entities.create();
let mut entity = world.entities.get_mut(entity_id).unwrap();
entity.set_type(EntityType::Cow);
entity.set_position([0.0, 50.0, 0.0]);
} }
fn update(&self, server: &Server, mut worlds: WorldsMut) { fn update(&self, server: &Server, mut worlds: WorldsMut) {

View file

@ -59,9 +59,9 @@ impl<'a> ChunksMut<'a> {
Self(chunks) Self(chunks)
} }
pub fn create(&mut self, pos: ChunkPos) -> bool { pub fn create(&mut self, pos: impl Into<ChunkPos>) -> bool {
let chunk = Chunk::new(self.section_count, self.server.current_tick()); let chunk = Chunk::new(self.section_count, self.server.current_tick());
self.0.chunks.insert(pos, chunk).is_none() self.0.chunks.insert(pos.into(), chunk).is_none()
} }
pub fn delete(&mut self, pos: ChunkPos) -> bool { pub fn delete(&mut self, pos: ChunkPos) -> bool {
@ -358,14 +358,12 @@ fn build_heightmap(sections: &[ChunkSection], heightmap: &mut Vec<i64>) {
} }
fn encode_paletted_container( fn encode_paletted_container(
entries: impl ExactSizeIterator<Item = u16> + Clone, mut entries: impl ExactSizeIterator<Item = u16> + Clone,
min_bits_per_idx: usize, min_bits_per_idx: usize,
direct_threshold: usize, direct_threshold: usize,
direct_bits_per_idx: usize, direct_bits_per_idx: usize,
w: &mut impl Write, w: &mut impl Write,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let entries_len = entries.len();
let mut palette = Vec::new(); let mut palette = Vec::new();
for entry in entries.clone() { for entry in entries.clone() {
@ -391,10 +389,12 @@ fn encode_paletted_container(
VarInt(u64_count as i32).encode(w)?; VarInt(u64_count as i32).encode(w)?;
for entry in entries { for _ in 0..idxs_per_u64 {
let mut val = 0u64; let mut val = 0u64;
for i in 0..idxs_per_u64 { for i in 0..idxs_per_u64 {
val |= (entry as u64) << (i * direct_bits_per_idx); if let Some(entry) = entries.next() {
val |= (entry as u64) << (i * direct_bits_per_idx);
}
} }
val.encode(w)?; val.encode(w)?;
} }
@ -411,15 +411,17 @@ fn encode_paletted_container(
VarInt(u64_count as i32).encode(w)?; VarInt(u64_count as i32).encode(w)?;
for entry in entries { for _ in 0..u64_count {
let palette_idx = palette
.iter()
.position(|&e| e == entry)
.expect("entry should be in the palette") as u64;
let mut val = 0u64; let mut val = 0u64;
for i in 0..idxs_per_u64 { for i in 0..idxs_per_u64 {
val |= palette_idx << (i * bits_per_idx); if let Some(entry) = entries.next() {
let palette_idx = palette
.iter()
.position(|&e| e == entry)
.expect("entry should be in the palette") as u64;
val |= palette_idx << (i * bits_per_idx);
}
} }
val.encode(w)?; val.encode(w)?;
} }
@ -428,14 +430,6 @@ fn encode_paletted_container(
Ok(()) Ok(())
} }
/// Encode a paletted container where all values are the same.
fn encode_paletted_container_single(entry: u16, w: &mut impl Write) -> anyhow::Result<()> {
0u8.encode(w)?; // bits per idx
VarInt(entry as i32).encode(w)?; // single value
VarInt(0).encode(w)?; // data array length
Ok(())
}
/// Calculates the log base 2 rounded up. /// Calculates the log base 2 rounded up.
fn log2_ceil(n: usize) -> usize { fn log2_ceil(n: usize) -> usize {
n.next_power_of_two().trailing_zeros() as usize n.next_power_of_two().trailing_zeros() as usize

View file

@ -505,7 +505,9 @@ impl<'a> ClientMut<'a> {
self.0.loaded_entities.retain(|&id| { self.0.loaded_entities.retain(|&id| {
if let Some(entity) = entities.get(id) { if let Some(entity) = entities.get(id) {
if self.0.new_position.distance(entity.position()) <= view_dist as f64 * 16.0 { if self.0.new_position.distance(entity.position()) <= view_dist as f64 * 16.0 {
todo!("update entity"); if let Some(meta) = entity.updated_metadata_packet(id) {
send_packet(&mut self.0.send, meta);
}
return true; return true;
} }
} }

View file

@ -16,7 +16,7 @@ use crate::packets::play::{
ClientPlayPacket, EntityMetadata, SpawnEntity, SpawnExperienceOrb, SpawnLivingEntity, ClientPlayPacket, EntityMetadata, SpawnEntity, SpawnExperienceOrb, SpawnLivingEntity,
SpawnPainting, SpawnPlayer, SpawnPainting, SpawnPlayer,
}; };
use crate::protocol::ReadToEnd; use crate::protocol::RawBytes;
use crate::slotmap::{Key, SlotMap}; use crate::slotmap::{Key, SlotMap};
use crate::util::aabb_from_bottom_and_size; use crate::util::aabb_from_bottom_and_size;
use crate::var_int::VarInt; use crate::var_int::VarInt;
@ -172,8 +172,8 @@ pub struct EntityId(Key);
impl EntityId { impl EntityId {
pub(crate) fn to_network_id(self) -> i32 { pub(crate) fn to_network_id(self) -> i32 {
// TODO: is ID 0 reserved? // ID 0 is reserved for clients.
self.0.index() as i32 self.0.index() as i32 + 1
} }
} }
@ -271,7 +271,7 @@ impl Entity {
pub(crate) fn initial_metadata_packet(&self, this_id: EntityId) -> Option<EntityMetadata> { pub(crate) fn initial_metadata_packet(&self, this_id: EntityId) -> Option<EntityMetadata> {
self.meta.initial_metadata().map(|meta| EntityMetadata { self.meta.initial_metadata().map(|meta| EntityMetadata {
entity_id: VarInt(this_id.to_network_id()), entity_id: VarInt(this_id.to_network_id()),
metadata: ReadToEnd(meta), metadata: RawBytes(meta),
}) })
} }
@ -281,7 +281,7 @@ impl Entity {
pub(crate) fn updated_metadata_packet(&self, this_id: EntityId) -> Option<EntityMetadata> { pub(crate) fn updated_metadata_packet(&self, this_id: EntityId) -> Option<EntityMetadata> {
self.meta.updated_metadata().map(|meta| EntityMetadata { self.meta.updated_metadata().map(|meta| EntityMetadata {
entity_id: VarInt(this_id.to_network_id()), entity_id: VarInt(this_id.to_network_id()),
metadata: ReadToEnd(meta), metadata: RawBytes(meta),
}) })
} }

View file

@ -31,7 +31,7 @@ pub use block_pos::BlockPos;
pub use chunk::{Chunk, ChunkPos, Chunks, ChunksMut}; pub use chunk::{Chunk, ChunkPos, Chunks, ChunksMut};
pub use client::{Client, ClientMut, Clients, ClientsMut}; pub use client::{Client, ClientMut, Clients, ClientsMut};
pub use config::{Biome, BiomeId, Config, Dimension, DimensionId}; pub use config::{Biome, BiomeId, Config, Dimension, DimensionId};
pub use entity::{Entities, EntitiesMut, Entity, EntityId}; pub use entity::{Entities, EntitiesMut, Entity, EntityId, EntityType};
pub use identifier::Identifier; pub use identifier::Identifier;
pub use server::{start_server, NewClientData, Server, ShutdownResult}; pub use server::{start_server, NewClientData, Server, ShutdownResult};
pub use text::{Text, TextFormat}; pub use text::{Text, TextFormat};

View file

@ -18,7 +18,7 @@ use vek::{Vec2, Vec3};
use crate::block_pos::BlockPos; use crate::block_pos::BlockPos;
use crate::byte_angle::ByteAngle; use crate::byte_angle::ByteAngle;
use crate::identifier::Identifier; use crate::identifier::Identifier;
use crate::protocol::{BoundedArray, BoundedInt, BoundedString, Decode, Encode, Nbt, ReadToEnd}; use crate::protocol::{BoundedArray, BoundedInt, BoundedString, Decode, Encode, Nbt, RawBytes};
use crate::var_int::VarInt; use crate::var_int::VarInt;
use crate::var_long::VarLong; use crate::var_long::VarLong;
use crate::Text; use crate::Text;
@ -1028,7 +1028,7 @@ pub mod play {
def_struct! { def_struct! {
EntityMetadata 0x4d { EntityMetadata 0x4d {
entity_id: VarInt, entity_id: VarInt,
metadata: ReadToEnd, metadata: RawBytes,
} }
} }
@ -1246,7 +1246,7 @@ pub mod play {
def_struct! { def_struct! {
PluginMessageServerbound 0x0a { PluginMessageServerbound 0x0a {
channel: Identifier, channel: Identifier,
data: ReadToEnd, data: RawBytes,
} }
} }

View file

@ -519,17 +519,17 @@ impl Decode for BitBox<u64> {
/// `Vec<u8>`. When encoding, the data is inserted into the packet with no /// `Vec<u8>`. When encoding, the data is inserted into the packet with no
/// length prefix. /// length prefix.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ReadToEnd(pub Vec<u8>); pub struct RawBytes(pub Vec<u8>);
impl Decode for ReadToEnd { impl Decode for RawBytes {
fn decode(r: &mut impl Read) -> anyhow::Result<Self> { fn decode(r: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = Vec::new(); let mut buf = Vec::new();
r.read_to_end(&mut buf)?; r.read_to_end(&mut buf)?;
Ok(ReadToEnd(buf)) Ok(RawBytes(buf))
} }
} }
impl Encode for ReadToEnd { impl Encode for RawBytes {
fn encode(&self, w: &mut impl Write) -> anyhow::Result<()> { fn encode(&self, w: &mut impl Write) -> anyhow::Result<()> {
w.write_all(&self.0).map_err(|e| e.into()) w.write_all(&self.0).map_err(|e| e.into())
} }