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::text::Color;
use valence::{
async_trait, ChunkPos, ClientMut, DimensionId, Server, ShutdownResult, Text, TextFormat,
WorldId, WorldsMut,
async_trait, ChunkPos, ClientMut, DimensionId, EntityType, Server, ShutdownResult, Text,
TextFormat, WorldId, WorldsMut,
};
pub fn main() -> ShutdownResult {
@ -83,14 +83,38 @@ impl Config for Game {
if x != -size && x != size - 1 && z != -size && z != size - 1 {
for z in 0..16 {
for x in 0..16 {
for y in 0..50 {
chunk.set_block_state(x, y, z, BlockState::STONE);
let block_x = pos.x * 16 + x as i32;
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) {

View file

@ -59,9 +59,9 @@ impl<'a> ChunksMut<'a> {
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());
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 {
@ -358,14 +358,12 @@ fn build_heightmap(sections: &[ChunkSection], heightmap: &mut Vec<i64>) {
}
fn encode_paletted_container(
entries: impl ExactSizeIterator<Item = u16> + Clone,
mut entries: impl ExactSizeIterator<Item = u16> + Clone,
min_bits_per_idx: usize,
direct_threshold: usize,
direct_bits_per_idx: usize,
w: &mut impl Write,
) -> anyhow::Result<()> {
let entries_len = entries.len();
let mut palette = Vec::new();
for entry in entries.clone() {
@ -391,11 +389,13 @@ fn encode_paletted_container(
VarInt(u64_count as i32).encode(w)?;
for entry in entries {
for _ in 0..idxs_per_u64 {
let mut val = 0u64;
for i in 0..idxs_per_u64 {
if let Some(entry) = entries.next() {
val |= (entry as u64) << (i * direct_bits_per_idx);
}
}
val.encode(w)?;
}
} else {
@ -411,16 +411,18 @@ fn encode_paletted_container(
VarInt(u64_count as i32).encode(w)?;
for entry in entries {
for _ in 0..u64_count {
let mut val = 0u64;
for i in 0..idxs_per_u64 {
if let Some(entry) = entries.next() {
let palette_idx = palette
.iter()
.position(|&e| e == entry)
.expect("entry should be in the palette") as u64;
let mut val = 0u64;
for i in 0..idxs_per_u64 {
val |= palette_idx << (i * bits_per_idx);
}
}
val.encode(w)?;
}
}
@ -428,14 +430,6 @@ fn encode_paletted_container(
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.
fn log2_ceil(n: usize) -> 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| {
if let Some(entity) = entities.get(id) {
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;
}
}

View file

@ -16,7 +16,7 @@ use crate::packets::play::{
ClientPlayPacket, EntityMetadata, SpawnEntity, SpawnExperienceOrb, SpawnLivingEntity,
SpawnPainting, SpawnPlayer,
};
use crate::protocol::ReadToEnd;
use crate::protocol::RawBytes;
use crate::slotmap::{Key, SlotMap};
use crate::util::aabb_from_bottom_and_size;
use crate::var_int::VarInt;
@ -172,8 +172,8 @@ pub struct EntityId(Key);
impl EntityId {
pub(crate) fn to_network_id(self) -> i32 {
// TODO: is ID 0 reserved?
self.0.index() as i32
// ID 0 is reserved for clients.
self.0.index() as i32 + 1
}
}
@ -271,7 +271,7 @@ impl Entity {
pub(crate) fn initial_metadata_packet(&self, this_id: EntityId) -> Option<EntityMetadata> {
self.meta.initial_metadata().map(|meta| EntityMetadata {
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> {
self.meta.updated_metadata().map(|meta| EntityMetadata {
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 client::{Client, ClientMut, Clients, ClientsMut};
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 server::{start_server, NewClientData, Server, ShutdownResult};
pub use text::{Text, TextFormat};

View file

@ -18,7 +18,7 @@ use vek::{Vec2, Vec3};
use crate::block_pos::BlockPos;
use crate::byte_angle::ByteAngle;
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_long::VarLong;
use crate::Text;
@ -1028,7 +1028,7 @@ pub mod play {
def_struct! {
EntityMetadata 0x4d {
entity_id: VarInt,
metadata: ReadToEnd,
metadata: RawBytes,
}
}
@ -1246,7 +1246,7 @@ pub mod play {
def_struct! {
PluginMessageServerbound 0x0a {
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
/// length prefix.
#[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> {
let mut buf = Vec::new();
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<()> {
w.write_all(&self.0).map_err(|e| e.into())
}