stevenarella/src/world/mod.rs

1441 lines
48 KiB
Rust
Raw Normal View History

2016-03-18 18:24:30 -04:00
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub use steven_blocks as block;
2016-03-18 18:24:30 -04:00
use crate::chunk_builder;
use crate::ecs;
use crate::entity::block_entity;
use crate::format;
use crate::protocol;
use crate::render;
use crate::shared::{Direction, Position};
use crate::types::hash::FNVHash;
use crate::types::{bit, nibble};
use cgmath::prelude::*;
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
use flate2::read::ZlibDecoder;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::hash::BuildHasherDefault;
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
use std::io::Read;
2016-03-18 18:24:30 -04:00
2016-03-24 15:20:26 -04:00
pub mod biome;
mod storage;
2016-03-24 15:20:26 -04:00
#[derive(Default)]
2016-03-18 18:24:30 -04:00
pub struct World {
2016-03-24 11:39:57 -04:00
chunks: HashMap<CPos, Chunk, BuildHasherDefault<FNVHash>>,
2016-03-24 17:47:11 -04:00
render_list: Vec<(i32, i32, i32)>,
light_updates: VecDeque<LightUpdate>,
2016-04-04 17:08:24 -04:00
block_entity_actions: VecDeque<BlockEntityAction>,
1.13.2 (404) multiprotocol support (#67) Adds support for 1.13.2 protocol (404) Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support Metadata: * Support 1.13.2 slot data format, bool and varint item id, optional damage (moved to NBT) https://wiki.vg/index.php?title=Slot_Data&type=revision&diff=14363&oldid=7835 Packets: * Add 1.13.2 packets, and implement all the command data parsers https://wiki.vg/Command_Data#Parsers * Send new plugin channel minecraft:brand https://wiki.vg/Plugin_channels#minecraft:brand * Add 1.13.2 metadata format, with shifted IDs https://wiki.vg/Entity_metadata#Entity_Metadata_Format * Implement particle entity metadata * Add structures for 16 new packets Blocks: The Flattening: * Assign flattened IDs in correct order using new 'offset' macro token * Assign hierarchical (pre-flattening) block IDs sequentially by counting Some data * Split VANILLA_ID_MAP into flat/hier struct, to support before and after the flattening * Extend travis build time to 20 minutes because the blocks macro takes a long time * Support both flat/hier blocks by passing protocol_version to by_vanilla_id Add block states and offsets for all blocks, replacing metadata for 1.13+: * Add stripped logs and what was Log2 to Log * Add the Wood blocks, should be called bark, previously Axis::None Log * Add leaves distance and offset * Add jungle/acacia to Leaves moved from Leaves2 * Add dispenser offsets, direction * Add note block states * Add offset None to Missing253 and Missing254, no holes in block states of 1.13.2 * Add bed colors * Add seagrass, tall seagrass, remove redundant deadgrass, and piston offset * Add torch, TNT, fire offsets, remove slabs * Add furnance offset, merges lit into a property * Add pressure plate offsets, new pressure plates, redstone ore/lit merged * Add lever offsets, new directions from ceiling/floor, rename LeverDirections * Add redstone torch offsets, new blocks since lit/unlit is now merged, and standing/wall is split * Change lever to split face/facing, rm LeverDirection, add AttachedFace * Add stone button offsets, face/facing similar to lever * Move face/facing data and variant to AttachedFace, reuse for lever/stonebutton * Add data_with_facing_and_powered() to AttachedFace, for lever/stonebutton * Add wooden button offsets each wood * Add pumpkin without a face * Add carved pumpkin, portal offsets * Add lit pumpkin (as jack-o-lantern) offsets after carved pumpkin * Add repeater offsets, merged into Repeater * Change brown mushroom block to booleans instead of MushroomVariant * Add mushroom block offsets, red/brown mushroom blocks, and a new mushroom stem block * Add command block, cobblestone walls, and flower pot offsets Empty flower pot, and potted plants including saplings. Rename variant DarkOak to DarkOakSaplings because it is a sapling, and remove the duplicate Dandelion variant which causes duplicate blocks. * Increase recursion limit in steven_blocks * Add colored banner offsets * Add wooden slab including double slab, in a different position for pre-1.13 and 1.13 * StoneSlabVariant::Wood -> StoneSlabVariant::PetrifiedWood * Add fence_gate_offset() for wooden fence gates * Add frosted ice age, offset * Add new blocks: kelp, turtle egg, coral, coral fans, sea pickle, blue ice, smooth stone * Add new blocks: conduit, void air, cave aid, bubble column, last of the 1.13 blocks
2018-12-29 00:11:42 -05:00
protocol_version: i32,
pub modded_block_ids: HashMap<usize, String>,
2016-04-04 17:08:24 -04:00
}
#[derive(Clone, Debug)]
pub enum BlockEntityAction {
Create(Position),
Remove(Position),
UpdateSignText(
Box<(
Position,
format::Component,
format::Component,
format::Component,
format::Component,
)>,
),
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum LightType {
Block,
Sky,
}
impl LightType {
fn get_light(self, world: &World, pos: Position) -> u8 {
match self {
LightType::Block => world.get_block_light(pos),
LightType::Sky => world.get_sky_light(pos),
}
}
fn set_light(self, world: &mut World, pos: Position, light: u8) {
match self {
LightType::Block => world.set_block_light(pos, light),
LightType::Sky => world.set_sky_light(pos, light),
}
}
}
struct LightUpdate {
ty: LightType,
pos: Position,
2016-03-18 18:24:30 -04:00
}
impl World {
1.13.2 (404) multiprotocol support (#67) Adds support for 1.13.2 protocol (404) Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support Metadata: * Support 1.13.2 slot data format, bool and varint item id, optional damage (moved to NBT) https://wiki.vg/index.php?title=Slot_Data&type=revision&diff=14363&oldid=7835 Packets: * Add 1.13.2 packets, and implement all the command data parsers https://wiki.vg/Command_Data#Parsers * Send new plugin channel minecraft:brand https://wiki.vg/Plugin_channels#minecraft:brand * Add 1.13.2 metadata format, with shifted IDs https://wiki.vg/Entity_metadata#Entity_Metadata_Format * Implement particle entity metadata * Add structures for 16 new packets Blocks: The Flattening: * Assign flattened IDs in correct order using new 'offset' macro token * Assign hierarchical (pre-flattening) block IDs sequentially by counting Some data * Split VANILLA_ID_MAP into flat/hier struct, to support before and after the flattening * Extend travis build time to 20 minutes because the blocks macro takes a long time * Support both flat/hier blocks by passing protocol_version to by_vanilla_id Add block states and offsets for all blocks, replacing metadata for 1.13+: * Add stripped logs and what was Log2 to Log * Add the Wood blocks, should be called bark, previously Axis::None Log * Add leaves distance and offset * Add jungle/acacia to Leaves moved from Leaves2 * Add dispenser offsets, direction * Add note block states * Add offset None to Missing253 and Missing254, no holes in block states of 1.13.2 * Add bed colors * Add seagrass, tall seagrass, remove redundant deadgrass, and piston offset * Add torch, TNT, fire offsets, remove slabs * Add furnance offset, merges lit into a property * Add pressure plate offsets, new pressure plates, redstone ore/lit merged * Add lever offsets, new directions from ceiling/floor, rename LeverDirections * Add redstone torch offsets, new blocks since lit/unlit is now merged, and standing/wall is split * Change lever to split face/facing, rm LeverDirection, add AttachedFace * Add stone button offsets, face/facing similar to lever * Move face/facing data and variant to AttachedFace, reuse for lever/stonebutton * Add data_with_facing_and_powered() to AttachedFace, for lever/stonebutton * Add wooden button offsets each wood * Add pumpkin without a face * Add carved pumpkin, portal offsets * Add lit pumpkin (as jack-o-lantern) offsets after carved pumpkin * Add repeater offsets, merged into Repeater * Change brown mushroom block to booleans instead of MushroomVariant * Add mushroom block offsets, red/brown mushroom blocks, and a new mushroom stem block * Add command block, cobblestone walls, and flower pot offsets Empty flower pot, and potted plants including saplings. Rename variant DarkOak to DarkOakSaplings because it is a sapling, and remove the duplicate Dandelion variant which causes duplicate blocks. * Increase recursion limit in steven_blocks * Add colored banner offsets * Add wooden slab including double slab, in a different position for pre-1.13 and 1.13 * StoneSlabVariant::Wood -> StoneSlabVariant::PetrifiedWood * Add fence_gate_offset() for wooden fence gates * Add frosted ice age, offset * Add new blocks: kelp, turtle egg, coral, coral fans, sea pickle, blue ice, smooth stone * Add new blocks: conduit, void air, cave aid, bubble column, last of the 1.13 blocks
2018-12-29 00:11:42 -05:00
pub fn new(protocol_version: i32) -> World {
World {
protocol_version,
..Default::default()
}
}
2016-03-18 18:24:30 -04:00
pub fn is_chunk_loaded(&self, x: i32, z: i32) -> bool {
self.chunks.contains_key(&CPos(x, z))
}
pub fn set_block(&mut self, pos: Position, b: block::Block) {
if self.set_block_raw(pos, b) {
self.update_block(pos);
}
}
fn set_block_raw(&mut self, pos: Position, b: block::Block) -> bool {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
2016-03-26 10:24:26 -04:00
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
2016-04-04 17:08:24 -04:00
if chunk.set_block(pos.x & 0xF, pos.y, pos.z & 0xF, b) {
if chunk.block_entities.contains_key(&pos) {
self.block_entity_actions
.push_back(BlockEntityAction::Remove(pos));
2016-04-04 17:08:24 -04:00
}
if block_entity::BlockEntityType::get_block_entity(b).is_some() {
self.block_entity_actions
.push_back(BlockEntityAction::Create(pos));
2016-04-04 17:08:24 -04:00
}
true
} else {
false
}
2016-03-18 18:24:30 -04:00
}
pub fn update_block(&mut self, pos: Position) {
for yy in -1..2 {
for zz in -1..2 {
for xx in -1..2 {
let bp = pos + (xx, yy, zz);
let current = self.get_block(bp);
let new = current.update_state(self, bp);
if current != new {
self.set_block_raw(bp, new);
}
self.set_dirty(bp.x >> 4, bp.y >> 4, bp.z >> 4);
self.update_light(bp, LightType::Block);
self.update_light(bp, LightType::Sky);
}
}
}
}
fn update_range(&mut self, x1: i32, y1: i32, z1: i32, x2: i32, y2: i32, z2: i32) {
for by in y1..y2 {
for bz in z1..z2 {
for bx in x1..x2 {
let bp = Position::new(bx, by, bz);
let current = self.get_block(bp);
let new = current.update_state(self, bp);
let sky_light = self.get_sky_light(bp);
let block_light = self.get_block_light(bp);
if current != new {
self.set_block_raw(bp, new);
// Restore old lighting
self.set_sky_light(bp, sky_light);
self.set_block_light(bp, block_light);
}
}
}
}
}
pub fn get_block(&self, pos: Position) -> block::Block {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(chunk) => chunk.get_block(pos.x & 0xF, pos.y, pos.z & 0xF),
None => block::Missing {},
2016-03-18 18:24:30 -04:00
}
}
2016-03-19 12:32:13 -04:00
fn set_block_light(&mut self, pos: Position, light: u8) {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
chunk.set_block_light(pos.x & 0xF, pos.y, pos.z & 0xF, light);
}
2016-04-04 17:08:24 -04:00
pub fn get_block_light(&self, pos: Position) -> u8 {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(chunk) => chunk.get_block_light(pos.x & 0xF, pos.y, pos.z & 0xF),
None => 0,
}
}
fn set_sky_light(&mut self, pos: Position, light: u8) {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
chunk.set_sky_light(pos.x & 0xF, pos.y, pos.z & 0xF, light);
}
2016-04-04 17:08:24 -04:00
pub fn get_sky_light(&self, pos: Position) -> u8 {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(chunk) => chunk.get_sky_light(pos.x & 0xF, pos.y, pos.z & 0xF),
None => 15,
}
}
fn update_light(&mut self, pos: Position, ty: LightType) {
self.light_updates.push_back(LightUpdate { ty, pos });
}
2016-04-04 17:08:24 -04:00
pub fn add_block_entity_action(&mut self, action: BlockEntityAction) {
self.block_entity_actions.push_back(action);
}
#[allow(clippy::verbose_bit_mask)] // "llvm generates better code" for updates_performed & 0xFFF "on x86"
2016-04-04 17:08:24 -04:00
pub fn tick(&mut self, m: &mut ecs::Manager) {
use std::time::Instant;
let start = Instant::now();
let mut updates_performed = 0;
while !self.light_updates.is_empty() {
updates_performed += 1;
self.do_light_update();
2020-06-29 21:26:53 -04:00
if (updates_performed & 0xFFF == 0) && start.elapsed().subsec_nanos() >= 5000000 {
// 5 ms for light updates
break;
}
}
2016-04-04 17:08:24 -04:00
let sign_info: ecs::Key<block_entity::sign::SignInfo> = m.get_key();
while let Some(action) = self.block_entity_actions.pop_front() {
match action {
BlockEntityAction::Remove(pos) => {
if let Some(chunk) = self.chunks.get_mut(&CPos(pos.x >> 4, pos.z >> 4)) {
if let Some(entity) = chunk.block_entities.remove(&pos) {
m.remove_entity(entity);
}
}
}
2016-04-04 17:08:24 -04:00
BlockEntityAction::Create(pos) => {
if let Some(chunk) = self.chunks.get_mut(&CPos(pos.x >> 4, pos.z >> 4)) {
// Remove existing entity
if let Some(entity) = chunk.block_entities.remove(&pos) {
m.remove_entity(entity);
}
let block = chunk.get_block(pos.x & 0xF, pos.y, pos.z & 0xF);
if let Some(entity_type) =
block_entity::BlockEntityType::get_block_entity(block)
{
2016-04-04 17:08:24 -04:00
let entity = entity_type.create_entity(m, pos);
chunk.block_entities.insert(pos, entity);
}
}
}
BlockEntityAction::UpdateSignText(bx) => {
let (pos, line1, line2, line3, line4) = *bx;
2016-04-04 17:08:24 -04:00
if let Some(chunk) = self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
if let Some(entity) = chunk.block_entities.get(&pos) {
if let Some(sign) = m.get_component_mut(*entity, sign_info) {
sign.lines = [line1, line2, line3, line4];
2016-04-04 17:08:24 -04:00
sign.dirty = true;
}
}
}
}
}
}
}
fn do_light_update(&mut self) {
use std::cmp;
if let Some(update) = self.light_updates.pop_front() {
if update.pos.y < 0
|| update.pos.y > 255
|| !self.is_chunk_loaded(update.pos.x >> 4, update.pos.z >> 4)
{
return;
}
let block = self.get_block(update.pos).get_material();
// Find the brightest source of light nearby
let mut best = update.ty.get_light(self, update.pos);
let old = best;
for dir in Direction::all() {
let light = update.ty.get_light(self, update.pos.shift(dir));
if light > best {
best = light;
}
}
best = best.saturating_sub(cmp::max(1, block.absorbed_light));
// If the light from the block itself is brighter than the light passing through
// it use that.
if update.ty == LightType::Block && block.emitted_light != 0 {
best = cmp::max(best, block.emitted_light);
}
// Sky light doesn't decrease when going down at full brightness
if update.ty == LightType::Sky
&& block.absorbed_light == 0
&& update.ty.get_light(self, update.pos.shift(Direction::Up)) == 15
{
best = 15;
}
// Nothing to do, we are already at the right value
if best == old {
return;
}
// Use our new light value
update.ty.set_light(self, update.pos, best);
// Flag surrounding chunks as dirty
for yy in -1..2 {
for zz in -1..2 {
for xx in -1..2 {
let bp = update.pos + (xx, yy, zz);
self.set_dirty(bp.x >> 4, bp.y >> 4, bp.z >> 4);
}
}
}
// Update surrounding blocks
for dir in Direction::all() {
self.update_light(update.pos.shift(dir), update.ty);
}
}
}
2016-04-01 15:00:13 -04:00
pub fn copy_cloud_heightmap(&mut self, data: &mut [u8]) -> bool {
let mut dirty = false;
for c in self.chunks.values_mut() {
2016-04-01 15:00:13 -04:00
if c.heightmap_dirty {
dirty = true;
c.heightmap_dirty = false;
for xx in 0..16 {
for zz in 0..16 {
data[(((c.position.0 << 4) as usize + xx) & 0x1FF)
+ ((((c.position.1 << 4) as usize + zz) & 0x1FF) << 9)] =
c.heightmap[(zz << 4) | xx];
2016-04-01 15:00:13 -04:00
}
}
}
}
dirty
}
2016-03-24 17:47:11 -04:00
pub fn compute_render_list(&mut self, renderer: &mut render::Renderer) {
self.render_list.clear();
2016-03-24 19:27:22 -04:00
let mut valid_dirs = [false; 6];
for dir in Direction::all() {
let (ox, oy, oz) = dir.get_offset();
let dir_vec = cgmath::Vector3::new(ox as f32, oy as f32, oz as f32);
valid_dirs[dir.index()] = renderer.view_vector.dot(dir_vec) > -0.9;
2016-03-24 19:27:22 -04:00
}
let start = (
((renderer.camera.pos.x as i32) >> 4),
((renderer.camera.pos.y as i32) >> 4),
((renderer.camera.pos.z as i32) >> 4),
2016-03-24 19:27:22 -04:00
);
let mut process_queue = VecDeque::with_capacity(self.chunks.len() * 16);
process_queue.push_front((Direction::Invalid, start));
while let Some((from, pos)) = process_queue.pop_front() {
let (exists, cull) = if let Some((sec, rendered_on)) =
self.get_render_section_mut(pos.0, pos.1, pos.2)
{
2016-03-24 19:27:22 -04:00
if *rendered_on == renderer.frame_id {
continue;
}
*rendered_on = renderer.frame_id;
let min = cgmath::Point3::new(
pos.0 as f32 * 16.0,
-pos.1 as f32 * 16.0,
pos.2 as f32 * 16.0,
);
let bounds =
collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0));
if renderer.frustum.contains(&bounds) == collision::Relation::Out
&& from != Direction::Invalid
{
2016-03-24 19:27:22 -04:00
continue;
}
(
sec.is_some(),
sec.map_or(chunk_builder::CullInfo::all_vis(), |v| v.cull_info),
)
2016-03-24 19:27:22 -04:00
} else {
continue;
};
if exists {
self.render_list.push(pos);
}
for dir in Direction::all() {
let (ox, oy, oz) = dir.get_offset();
let opos = (pos.0 + ox, pos.1 + oy, pos.2 + oz);
if let Some((_, rendered_on)) = self.get_render_section_mut(opos.0, opos.1, opos.2)
{
2016-03-24 19:27:22 -04:00
if *rendered_on == renderer.frame_id {
continue;
}
if from == Direction::Invalid
|| (valid_dirs[dir.index()] && cull.is_visible(from, dir))
{
2016-03-24 19:27:22 -04:00
process_queue.push_back((dir.opposite(), opos));
2016-03-24 17:13:24 -04:00
}
}
}
}
2016-03-24 17:47:11 -04:00
}
pub fn get_render_list(&self) -> Vec<((i32, i32, i32), &render::ChunkBuffer)> {
self.render_list
.iter()
.map(|v| {
let chunk = self.chunks.get(&CPos(v.0, v.2)).unwrap();
let sec = chunk.sections[v.1 as usize].as_ref().unwrap();
(*v, &sec.render_buffer)
})
.collect()
2016-03-24 17:13:24 -04:00
}
2016-03-24 19:27:22 -04:00
pub fn get_section_mut(&mut self, x: i32, y: i32, z: i32) -> Option<&mut Section> {
if let Some(chunk) = self.chunks.get_mut(&CPos(x, z)) {
if let Some(sec) = chunk.sections[y as usize].as_mut() {
return Some(sec);
}
}
None
}
fn get_render_section_mut(
&mut self,
x: i32,
y: i32,
z: i32,
) -> Option<(Option<&mut Section>, &mut u32)> {
2016-03-24 19:27:22 -04:00
if y < 0 || y > 15 {
return None;
}
2016-03-24 17:13:24 -04:00
if let Some(chunk) = self.chunks.get_mut(&CPos(x, z)) {
2016-03-24 19:27:22 -04:00
let rendered = &mut chunk.sections_rendered_on[y as usize];
2016-03-24 17:13:24 -04:00
if let Some(sec) = chunk.sections[y as usize].as_mut() {
2016-03-24 19:27:22 -04:00
return Some((Some(sec), rendered));
2016-03-24 17:13:24 -04:00
}
2016-03-24 19:27:22 -04:00
return Some((None, rendered));
2016-03-24 17:13:24 -04:00
}
None
}
pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32)> {
let mut out = vec![];
for chunk in self.chunks.values_mut() {
2016-03-19 12:32:13 -04:00
for sec in &mut chunk.sections {
if let Some(sec) = sec.as_mut() {
if !sec.building && sec.dirty {
2016-03-24 17:13:24 -04:00
out.push((chunk.position.0, sec.y as i32, chunk.position.1));
2016-03-19 12:32:13 -04:00
}
}
}
}
out
}
fn set_dirty(&mut self, x: i32, y: i32, z: i32) {
if let Some(chunk) = self.chunks.get_mut(&CPos(x, z)) {
if let Some(sec) = chunk.sections.get_mut(y as usize).and_then(|v| v.as_mut()) {
sec.dirty = true;
}
}
}
2016-03-24 19:27:22 -04:00
pub fn is_section_dirty(&self, pos: (i32, i32, i32)) -> bool {
if let Some(chunk) = self.chunks.get(&CPos(pos.0, pos.2)) {
if let Some(sec) = chunk.sections[pos.1 as usize].as_ref() {
return sec.dirty && !sec.building;
}
}
false
}
pub fn set_building_flag(&mut self, pos: (i32, i32, i32)) {
if let Some(chunk) = self.chunks.get_mut(&CPos(pos.0, pos.2)) {
if let Some(sec) = chunk.sections[pos.1 as usize].as_mut() {
sec.building = true;
sec.dirty = false;
}
}
2016-03-19 12:32:13 -04:00
}
pub fn reset_building_flag(&mut self, pos: (i32, i32, i32)) {
if let Some(chunk) = self.chunks.get_mut(&CPos(pos.0, pos.2)) {
if let Some(section) = chunk.sections[pos.1 as usize].as_mut() {
section.building = false;
}
}
}
2016-03-19 13:34:12 -04:00
pub fn flag_dirty_all(&mut self) {
for chunk in self.chunks.values_mut() {
2016-03-19 13:34:12 -04:00
for sec in &mut chunk.sections {
if let Some(sec) = sec.as_mut() {
sec.dirty = true;
}
}
}
}
2016-03-19 12:32:13 -04:00
pub fn capture_snapshot(&self, x: i32, y: i32, z: i32, w: i32, h: i32, d: i32) -> Snapshot {
use std::cmp::{max, min};
2016-03-19 12:32:13 -04:00
let mut snapshot = Snapshot {
blocks: storage::BlockStorage::new_default((w * h * d) as usize, block::Missing {}),
2016-03-19 12:32:13 -04:00
block_light: nibble::Array::new((w * h * d) as usize),
sky_light: nibble::Array::new((w * h * d) as usize),
biomes: vec![0; (w * d) as usize],
x,
y,
z,
w,
_h: h,
d,
2016-03-19 12:32:13 -04:00
};
for i in 0..(w * h * d) as usize {
2016-03-19 12:32:13 -04:00
snapshot.sky_light.set(i, 0xF);
}
let cx1 = x >> 4;
let cy1 = y >> 4;
let cz1 = z >> 4;
let cx2 = (x + w + 15) >> 4;
let cy2 = (y + h + 15) >> 4;
let cz2 = (z + d + 15) >> 4;
for cx in cx1..cx2 {
for cz in cz1..cz2 {
2016-03-19 12:32:13 -04:00
let chunk = match self.chunks.get(&CPos(cx, cz)) {
Some(val) => val,
None => continue,
};
let x1 = min(16, max(0, x - (cx << 4)));
let x2 = min(16, max(0, x + w - (cx << 4)));
let z1 = min(16, max(0, z - (cz << 4)));
let z2 = min(16, max(0, z + d - (cz << 4)));
2016-03-19 12:32:13 -04:00
for cy in cy1..cy2 {
2016-03-19 12:32:13 -04:00
if cy < 0 || cy > 15 {
continue;
}
let section = &chunk.sections[cy as usize];
let y1 = min(16, max(0, y - (cy << 4)));
let y2 = min(16, max(0, y + h - (cy << 4)));
2016-03-19 12:32:13 -04:00
for yy in y1..y2 {
for zz in z1..z2 {
for xx in x1..x2 {
2016-03-19 12:32:13 -04:00
let ox = xx + (cx << 4);
let oy = yy + (cy << 4);
let oz = zz + (cz << 4);
match section.as_ref() {
Some(sec) => {
snapshot.set_block(ox, oy, oz, sec.get_block(xx, yy, zz));
snapshot.set_block_light(
ox,
oy,
oz,
sec.get_block_light(xx, yy, zz),
);
snapshot.set_sky_light(
ox,
oy,
oz,
sec.get_sky_light(xx, yy, zz),
);
}
2016-03-19 12:32:13 -04:00
None => {
snapshot.set_block(ox, oy, oz, block::Air {});
}
2016-03-19 12:32:13 -04:00
}
}
}
}
}
for zz in z1..z2 {
for xx in x1..x2 {
2016-03-24 15:20:26 -04:00
let ox = xx + (cx << 4);
let oz = zz + (cz << 4);
snapshot.set_biome(ox, oz, chunk.get_biome(xx, zz));
}
}
2016-03-19 12:32:13 -04:00
}
}
snapshot
}
2016-03-21 10:05:13 -04:00
2016-04-04 17:08:24 -04:00
pub fn unload_chunk(&mut self, x: i32, z: i32, m: &mut ecs::Manager) {
if let Some(chunk) = self.chunks.remove(&CPos(x, z)) {
for entity in chunk.block_entities.values() {
m.remove_entity(*entity);
}
}
}
pub fn load_chunks18(
&mut self,
new: bool,
skylight: bool,
chunk_metas: &[crate::protocol::packet::ChunkMeta],
data: Vec<u8>,
) -> Result<(), protocol::Error> {
let mut data = std::io::Cursor::new(data);
for chunk_meta in chunk_metas {
let x = chunk_meta.x;
let z = chunk_meta.z;
let mask = chunk_meta.bitmask;
self.load_chunk18(x, z, new, skylight, mask, &mut data)?;
}
Ok(())
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
fn dirty_chunks_by_bitmask(&mut self, x: i32, z: i32, mask: u16) {
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask & (1 << i) == 0 {
continue;
}
for pos in [
(-1, 0, 0),
(1, 0, 0),
(0, -1, 0),
(0, 1, 0),
(0, 0, -1),
(0, 0, 1),
]
.iter()
{
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
self.flag_section_dirty(x + pos.0, i as i32 + pos.1, z + pos.2);
}
self.update_range(
(x << 4) - 1,
(i << 4) - 1,
(z << 4) - 1,
(x << 4) + 17,
(i << 4) + 17,
(z << 4) + 17,
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
);
}
}
pub fn load_chunk18(
&mut self,
x: i32,
z: i32,
new: bool,
_skylight: bool,
mask: u16,
data: &mut std::io::Cursor<Vec<u8>>,
) -> Result<(), protocol::Error> {
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
use byteorder::ReadBytesExt;
let cpos = CPos(x, z);
{
let chunk = if new {
self.chunks.insert(cpos, Chunk::new(cpos));
self.chunks.get_mut(&cpos).unwrap()
} else {
if !self.chunks.contains_key(&cpos) {
return Ok(());
}
self.chunks.get_mut(&cpos).unwrap()
};
for i in 0..16 {
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
if chunk.sections[i].is_none() {
let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none());
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0;
if !fill_sky || mask & (1 << i) != 0 {
chunk.sections[i] = Some(Section::new(i as u8, fill_sky));
}
}
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
section.dirty = true;
for bi in 0..4096 {
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
let id = data.read_u16::<byteorder::LittleEndian>()?;
section.blocks.set(
bi,
block::Block::by_vanilla_id(
id as usize,
self.protocol_version,
&self.modded_block_ids,
),
);
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
// Spawn block entities
let b = section.blocks.get(bi);
if block_entity::BlockEntityType::get_block_entity(b).is_some() {
let pos = Position::new(
(bi & 0xF) as i32,
(bi >> 8) as i32,
((bi >> 4) & 0xF) as i32,
) + (
chunk.position.0 << 4,
(i << 4) as i32,
chunk.position.1 << 4,
);
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
if chunk.block_entities.contains_key(&pos) {
self.block_entity_actions
.push_back(BlockEntityAction::Remove(pos))
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
self.block_entity_actions
.push_back(BlockEntityAction::Create(pos))
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
}
}
for i in 0..16 {
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
data.read_exact(&mut section.block_light.data)?;
}
for i in 0..16 {
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
data.read_exact(&mut section.sky_light.data)?;
}
if new {
data.read_exact(&mut chunk.biomes)?;
}
chunk.calculate_heightmap();
}
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
self.dirty_chunks_by_bitmask(x, z, mask);
Ok(())
}
pub fn load_chunks17(
&mut self,
chunk_column_count: u16,
data_length: i32,
skylight: bool,
data: &[u8],
) -> Result<(), protocol::Error> {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
let compressed_chunk_data = &data[0..data_length as usize];
let metadata = &data[data_length as usize..];
let mut zlib = ZlibDecoder::new(std::io::Cursor::new(compressed_chunk_data.to_vec()));
let mut chunk_data = Vec::new();
zlib.read_to_end(&mut chunk_data)?;
let mut chunk_data = std::io::Cursor::new(chunk_data);
// Chunk metadata
let mut metadata = std::io::Cursor::new(metadata);
for _i in 0..chunk_column_count {
use byteorder::ReadBytesExt;
let x = metadata.read_i32::<byteorder::BigEndian>()?;
let z = metadata.read_i32::<byteorder::BigEndian>()?;
let mask = metadata.read_u16::<byteorder::BigEndian>()?;
let mask_add = metadata.read_u16::<byteorder::BigEndian>()?;
let new = true;
self.load_uncompressed_chunk17(x, z, new, skylight, mask, mask_add, &mut chunk_data)?;
}
Ok(())
}
pub fn load_chunk17(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u16,
mask_add: u16,
compressed_data: Vec<u8>,
) -> Result<(), protocol::Error> {
let mut zlib = ZlibDecoder::new(std::io::Cursor::new(compressed_data.to_vec()));
let mut data = Vec::new();
zlib.read_to_end(&mut data)?;
let skylight = true;
self.load_uncompressed_chunk17(
x,
z,
new,
skylight,
mask,
mask_add,
&mut std::io::Cursor::new(data),
)
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
}
#[allow(clippy::needless_range_loop)]
fn load_uncompressed_chunk17(
&mut self,
x: i32,
z: i32,
new: bool,
skylight: bool,
mask: u16,
mask_add: u16,
data: &mut std::io::Cursor<Vec<u8>>,
) -> Result<(), protocol::Error> {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
let cpos = CPos(x, z);
{
let chunk = if new {
self.chunks.insert(cpos, Chunk::new(cpos));
self.chunks.get_mut(&cpos).unwrap()
} else {
if !self.chunks.contains_key(&cpos) {
return Ok(());
}
self.chunks.get_mut(&cpos).unwrap()
};
// Block type array - whole byte per block
let mut block_types = [[0u8; 4096]; 16];
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if chunk.sections[i].is_none() {
let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none());
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0;
if !fill_sky || mask & (1 << i) != 0 {
chunk.sections[i] = Some(Section::new(i as u8, fill_sky));
}
}
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
section.dirty = true;
data.read_exact(&mut block_types[i])?;
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
// Block metadata array - half byte per block
let mut block_meta: [nibble::Array; 16] = [
// TODO: cleanup this initialization
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
];
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask & (1 << i) == 0 {
continue;
}
data.read_exact(&mut block_meta[i].data)?;
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
// Block light array - half byte per block
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
data.read_exact(&mut section.block_light.data)?;
}
// Sky light array - half byte per block - only if 'skylight' is true
if skylight {
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
data.read_exact(&mut section.sky_light.data)?;
}
}
// Add array - half byte per block - uses secondary bitmask
let mut block_add: [nibble::Array; 16] = [
// TODO: cleanup this initialization
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
nibble::Array::new(16 * 16 * 16),
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
];
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask_add & (1 << i) == 0 {
continue;
}
data.read_exact(&mut block_add[i].data)?;
}
// Now that we have the block types, metadata, and add, combine to initialize the blocks
for i in 0..16 {
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
for bi in 0..4096 {
let id = ((block_add[i].get(bi) as u16) << 12)
| ((block_types[i][bi] as u16) << 4)
| (block_meta[i].get(bi) as u16);
section.blocks.set(
bi,
block::Block::by_vanilla_id(
id as usize,
self.protocol_version,
&self.modded_block_ids,
),
);
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
// Spawn block entities
let b = section.blocks.get(bi);
if block_entity::BlockEntityType::get_block_entity(b).is_some() {
let pos = Position::new(
(bi & 0xF) as i32,
(bi >> 8) as i32,
((bi >> 4) & 0xF) as i32,
) + (
chunk.position.0 << 4,
(i << 4) as i32,
chunk.position.1 << 4,
);
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
if chunk.block_entities.contains_key(&pos) {
self.block_entity_actions
.push_back(BlockEntityAction::Remove(pos))
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
}
self.block_entity_actions
.push_back(BlockEntityAction::Create(pos))
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
}
}
}
if new {
data.read_exact(&mut chunk.biomes)?;
}
chunk.calculate_heightmap();
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
}
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
self.dirty_chunks_by_bitmask(x, z, mask);
1.8.9 (47) multiprotocol support (#57) Protocol 47 (1.8.9-1.8) is the biggest multiprotocol (https://github.com/iceiix/steven/issues/18) change yet: * New chunk format (load_chunk18) * New metadata format (Metadata18) * New packets and changes to 13 packets References: http://wiki.vg/index.php?title=Protocol&oldid=7368 https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite https://wiki.vg/Protocol_History#1.8 https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/protocol.json 1.8 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=6124 1.9 chunk format: https://wiki.vg/index.php?title=Chunk_Format&oldid=7411 1.8 vs 1.9: https://wiki.vg/index.php?title=Chunk_Format&diff=7411&oldid=6124 https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/section.js https://github.com/PrismarineJS/prismarine-chunk/blob/master/src/pc/1.8/chunk.js Details: * Add 1.8.9 packet IDs from https://github.com/iceiix/steven/pull/37 * Add ChunkDataBulk, parse the ChunkMeta and save data in Vec<u8> * Add EntityEquipment u16 variant, EntityStatus, ChunkData u16 variants * SpawnPlayer with added held item https://wiki.vg/Protocol_History#15w31a Removed Current Item short from Spawn Player (0x0C) * SpawnObject no UUID and optional velocity https://wiki.vg/index.php?title=Protocol&oldid=7368#Spawn_Object https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Object (0x0E) Spawn Object always sends velocity, even if data is 0 * SpawnMob no UUID variant https://wiki.vg/Protocol_History#15w31a Added Entity UUID after entity ID to Spawn Mob (0x0F) * Maps packet without tracking position boolean https://wiki.vg/index.php?title=Protocol&oldid=7368#Map https://wiki.vg/Protocol_History#15w34a Added tracking position boolean to Map (0x34) * Update Entity NBT was removed and Bossbar added (both 0x49) >1.8 https://wiki.vg/index.php?title=Protocol&oldid=7368#Update_Entity_NBT https://wiki.vg/Protocol_History#15w31a Removed Update Entity NBT Packet (0x49) Added Boss Bar packet (0x4 * Use entity without hands https://wiki.vg/index.php?title=Protocol&oldid=7368#Use_Entity https://wiki.vg/Protocol_History#15w31a Added VarInt enum for selected hand in Use Entity (0x02); only sent if type is interact or interact at * Player block placement, held item stack and face byte variant https://wiki.vg/index.php?title=Protocol&oldid=7368#Player_Block_Placement https://wiki.vg/Protocol_History#15w31a Face for Player Block Placement is now a VarInt enum instead of a byte Replaced held item (slot) with VarInt enum selected hand in Player Block Placement * Arm swing without hands, a packet with no fields, uses a ZST https://wiki.vg/index.php?title=Protocol&oldid=7368#Animation_2 https://github.com/iceiix/steven/pull/57#issuecomment-444289008 https://doc.rust-lang.org/nomicon/exotic-sizes.html * ClickWindow uses u8 mode, same as in 15w39c * ClientSettings without hands * SpectateTeleport is added before ResourcePackStatus * Copy load_chunk to load_chunk19 and load_chunk18 * 1.8 chunk reading implementation, load_chunk18 * Support both metadata formats, Metadata18/Metadata19 * Remove fmt::Debug * Implement formatting in MetadataBase and bounce through fmt::Debug
2018-12-09 15:03:55 -05:00
Ok(())
}
pub fn load_chunk19(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u16,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
self.load_chunk19_or_115(true, x, z, new, mask, data)
}
pub fn load_chunk115(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u16,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
self.load_chunk19_or_115(false, x, z, new, mask, data)
}
#[allow(clippy::or_fun_call)]
fn load_chunk19_or_115(
&mut self,
read_biomes: bool,
x: i32,
z: i32,
new: bool,
mask: u16,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
use crate::protocol::{LenPrefixed, Serializable, VarInt};
2016-03-21 10:05:13 -04:00
use byteorder::ReadBytesExt;
use std::io::Cursor;
2016-03-21 10:05:13 -04:00
let mut data = Cursor::new(data);
let cpos = CPos(x, z);
2016-03-21 12:36:50 -04:00
{
let chunk = if new {
self.chunks.insert(cpos, Chunk::new(cpos));
self.chunks.get_mut(&cpos).unwrap()
} else {
if !self.chunks.contains_key(&cpos) {
return Ok(());
}
self.chunks.get_mut(&cpos).unwrap()
};
2016-03-21 10:05:13 -04:00
for i in 0..16 {
if chunk.sections[i].is_none() {
let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none());
fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0;
if !fill_sky || mask & (1 << i) != 0 {
chunk.sections[i] = Some(Section::new(i as u8, fill_sky));
}
}
2016-03-21 12:36:50 -04:00
if mask & (1 << i) == 0 {
continue;
}
let section = chunk.sections[i as usize].as_mut().unwrap();
section.dirty = true;
if self.protocol_version >= 451 {
let _block_count = data.read_u16::<byteorder::LittleEndian>()?;
// TODO: use block_count
}
2016-03-21 12:36:50 -04:00
let mut bit_size = data.read_u8()?;
let mut mappings: HashMap<usize, block::Block, BuildHasherDefault<FNVHash>> =
HashMap::with_hasher(BuildHasherDefault::default());
2016-04-02 20:26:31 -04:00
if bit_size == 0 {
bit_size = 13;
} else {
let count = VarInt::read_from(&mut data)?.0;
for i in 0..count {
let id = VarInt::read_from(&mut data)?.0;
let bl = block::Block::by_vanilla_id(
id as usize,
self.protocol_version,
&self.modded_block_ids,
);
2016-04-21 16:20:28 -04:00
mappings.insert(i as usize, bl);
2016-03-21 12:36:50 -04:00
}
}
let bits = LenPrefixed::<VarInt, u64>::read_from(&mut data)?.data;
let padded = self.protocol_version >= 736;
let m = bit::Map::from_raw(bits, bit_size as usize, padded);
2016-03-21 12:36:50 -04:00
for bi in 0..4096 {
2016-04-21 16:20:28 -04:00
let id = m.get(bi);
section.blocks.set(
bi,
mappings
.get(&id)
.cloned()
// TODO: fix or_fun_call, but do not re-borrow self
.unwrap_or(block::Block::by_vanilla_id(
id,
self.protocol_version,
&self.modded_block_ids,
)),
);
2016-04-21 16:20:28 -04:00
// Spawn block entities
let b = section.blocks.get(bi);
if block_entity::BlockEntityType::get_block_entity(b).is_some() {
2016-04-04 17:08:24 -04:00
let pos = Position::new(
(bi & 0xF) as i32,
(bi >> 8) as i32,
((bi >> 4) & 0xF) as i32,
) + (
chunk.position.0 << 4,
(i << 4) as i32,
chunk.position.1 << 4,
);
2016-04-04 17:08:24 -04:00
if chunk.block_entities.contains_key(&pos) {
self.block_entity_actions
.push_back(BlockEntityAction::Remove(pos))
2016-04-04 17:08:24 -04:00
}
self.block_entity_actions
.push_back(BlockEntityAction::Create(pos))
2016-04-04 17:08:24 -04:00
}
2016-03-21 12:36:50 -04:00
}
if self.protocol_version >= 451 {
// Skylight in update skylight packet for 1.14+
} else {
data.read_exact(&mut section.block_light.data)?;
data.read_exact(&mut section.sky_light.data)?;
}
2016-03-21 12:36:50 -04:00
}
2016-03-24 15:20:26 -04:00
if read_biomes && new {
data.read_exact(&mut chunk.biomes)?;
2016-03-24 15:20:26 -04:00
}
2016-04-01 15:00:13 -04:00
chunk.calculate_heightmap();
2016-03-21 12:36:50 -04:00
}
2016-03-24 15:20:26 -04:00
1.7.10 (5) multiprotocol support (#64) Adds 1.7.10 protocol version 5 support, a major update with significant changes. Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support * Add v1_7_10 protocol packet structures and IDs * EncryptionRequest/Response i16 variant in login protocol * 1.7.10 slot NBT data parsing * Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson * 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17 * Extract dirty_chunks_by_bitmask from load_chunks17/18/19 * Implement keepalive i32 handler * Send PlayerPositionLook_HeadY * Send PlayerBlockPlacement_u8_Item_u8y * Handle JoinGame_i8_NoDebug * Handle SpawnPlayer_i32_HeldItem_String * BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround * UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround * Send feet_y = head_y - 1.62, fixes Illegal stance https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position > Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”. > Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc… * Set on_ground = true in entity teleport, fixes bouncing * Implement block change, fix metadata/id packing, bounce _u8 through on_block_change * Implement on_multi_block_change_u16, used with explosions
2018-12-15 22:56:54 -05:00
self.dirty_chunks_by_bitmask(x, z, mask);
2016-03-21 12:36:50 -04:00
Ok(())
}
2016-03-21 10:05:13 -04:00
2016-03-21 12:36:50 -04:00
fn flag_section_dirty(&mut self, x: i32, y: i32, z: i32) {
if y < 0 || y > 15 {
return;
}
let cpos = CPos(x, z);
if let Some(chunk) = self.chunks.get_mut(&cpos) {
if let Some(sec) = chunk.sections[y as usize].as_mut() {
sec.dirty = true;
2016-03-21 10:05:13 -04:00
}
}
}
2016-03-19 12:32:13 -04:00
}
impl block::WorldAccess for World {
fn get_block(&self, pos: Position) -> block::Block {
World::get_block(self, pos)
}
}
2016-03-19 12:32:13 -04:00
pub struct Snapshot {
2016-04-20 15:07:39 -04:00
blocks: storage::BlockStorage,
2016-03-19 12:32:13 -04:00
block_light: nibble::Array,
sky_light: nibble::Array,
biomes: Vec<u8>,
x: i32,
y: i32,
z: i32,
w: i32,
2016-03-26 06:19:16 -04:00
_h: i32,
2016-03-19 12:32:13 -04:00
d: i32,
}
impl Snapshot {
pub fn make_relative(&mut self, x: i32, y: i32, z: i32) {
self.x = x;
self.y = y;
self.z = z;
}
2016-03-23 17:07:49 -04:00
pub fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block {
2016-04-20 15:07:39 -04:00
self.blocks.get(self.index(x, y, z))
2016-03-19 12:32:13 -04:00
}
2016-03-23 17:07:49 -04:00
pub fn set_block(&mut self, x: i32, y: i32, z: i32, b: block::Block) {
2016-03-19 12:32:13 -04:00
let idx = self.index(x, y, z);
2016-04-20 15:07:39 -04:00
self.blocks.set(idx, b);
2016-03-19 12:32:13 -04:00
}
pub fn get_block_light(&self, x: i32, y: i32, z: i32) -> u8 {
self.block_light.get(self.index(x, y, z))
}
pub fn set_block_light(&mut self, x: i32, y: i32, z: i32, l: u8) {
let idx = self.index(x, y, z);
self.block_light.set(idx, l);
}
pub fn get_sky_light(&self, x: i32, y: i32, z: i32) -> u8 {
self.sky_light.get(self.index(x, y, z))
}
pub fn set_sky_light(&mut self, x: i32, y: i32, z: i32, l: u8) {
let idx = self.index(x, y, z);
self.sky_light.set(idx, l);
}
2016-03-24 15:20:26 -04:00
pub fn get_biome(&self, x: i32, z: i32) -> biome::Biome {
2016-04-04 10:05:24 -04:00
biome::Biome::by_id(self.biomes[((x - self.x) + ((z - self.z) * self.w)) as usize] as usize)
2016-03-24 15:20:26 -04:00
}
pub fn set_biome(&mut self, x: i32, z: i32, b: biome::Biome) {
2016-04-04 10:05:24 -04:00
self.biomes[((x - self.x) + ((z - self.z) * self.w)) as usize] = b.id as u8;
2016-03-24 15:20:26 -04:00
}
2016-03-19 12:32:13 -04:00
#[inline]
fn index(&self, x: i32, y: i32, z: i32) -> usize {
((x - self.x) + ((z - self.z) * self.w) + ((y - self.y) * self.w * self.d)) as usize
}
2016-03-18 18:24:30 -04:00
}
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub struct CPos(i32, i32);
pub struct Chunk {
position: CPos,
sections: [Option<Section>; 16],
2016-03-24 19:27:22 -04:00
sections_rendered_on: [u32; 16],
2016-03-18 18:24:30 -04:00
biomes: [u8; 16 * 16],
2016-04-01 15:00:13 -04:00
heightmap: [u8; 16 * 16],
heightmap_dirty: bool,
2016-04-04 17:08:24 -04:00
block_entities: HashMap<Position, ecs::Entity, BuildHasherDefault<FNVHash>>,
2016-03-18 18:24:30 -04:00
}
impl Chunk {
fn new(pos: CPos) -> Chunk {
Chunk {
position: pos,
sections: [
None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None,
2016-03-18 18:24:30 -04:00
],
2016-03-24 19:27:22 -04:00
sections_rendered_on: [0; 16],
2016-03-18 18:24:30 -04:00
biomes: [0; 16 * 16],
2016-04-01 15:00:13 -04:00
heightmap: [0; 16 * 16],
heightmap_dirty: true,
2016-04-04 17:08:24 -04:00
block_entities: HashMap::with_hasher(BuildHasherDefault::default()),
2016-04-01 15:00:13 -04:00
}
}
fn calculate_heightmap(&mut self) {
for x in 0..16 {
for z in 0..16 {
let idx = ((z << 4) | x) as usize;
for yy in 0..256 {
2016-04-01 15:00:13 -04:00
let sy = 255 - yy;
if let block::Air { .. } = self.get_block(x, sy, z) {
continue;
2016-04-02 20:26:31 -04:00
}
2016-04-01 15:00:13 -04:00
self.heightmap[idx] = sy as u8;
break;
}
}
2016-03-18 18:24:30 -04:00
}
2016-04-01 15:00:13 -04:00
self.heightmap_dirty = true;
2016-03-18 18:24:30 -04:00
}
fn set_block(&mut self, x: i32, y: i32, z: i32, b: block::Block) -> bool {
2016-04-03 10:42:54 -04:00
let s_idx = y >> 4;
2016-03-18 18:24:30 -04:00
if s_idx < 0 || s_idx > 15 {
return false;
2016-03-18 18:24:30 -04:00
}
2016-04-03 10:42:54 -04:00
let s_idx = s_idx as usize;
if self.sections[s_idx].is_none() {
2016-03-23 17:07:49 -04:00
if let block::Air {} = b {
return false;
2016-03-18 18:24:30 -04:00
}
let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none());
self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky));
2016-03-18 18:24:30 -04:00
}
2016-04-01 15:00:13 -04:00
{
let section = self.sections[s_idx as usize].as_mut().unwrap();
if !section.set_block(x, y & 0xF, z, b) {
return false;
}
2016-04-01 15:00:13 -04:00
}
let idx = ((z << 4) | x) as usize;
match self.heightmap[idx].cmp(&(y as u8)) {
Ordering::Less => {
self.heightmap[idx] = y as u8;
self.heightmap_dirty = true;
}
Ordering::Equal => {
// Find a new lowest
for yy in 0..y {
let sy = y - yy - 1;
if let block::Air { .. } = self.get_block(x, sy, z) {
continue;
}
self.heightmap[idx] = sy as u8;
break;
2016-04-02 20:26:31 -04:00
}
self.heightmap_dirty = true;
2016-04-01 15:00:13 -04:00
}
Ordering::Greater => (),
2016-04-01 15:00:13 -04:00
}
true
2016-03-18 18:24:30 -04:00
}
2016-03-23 17:07:49 -04:00
fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block {
2016-03-18 18:24:30 -04:00
let s_idx = y >> 4;
if s_idx < 0 || s_idx > 15 {
return block::Missing {};
2016-03-18 18:24:30 -04:00
}
match self.sections[s_idx as usize].as_ref() {
Some(sec) => sec.get_block(x, y & 0xF, z),
None => block::Air {},
2016-03-18 18:24:30 -04:00
}
}
2016-03-24 15:20:26 -04:00
fn get_block_light(&self, x: i32, y: i32, z: i32) -> u8 {
let s_idx = y >> 4;
if s_idx < 0 || s_idx > 15 {
return 0;
}
match self.sections[s_idx as usize].as_ref() {
Some(sec) => sec.get_block_light(x, y & 0xF, z),
None => 0,
}
}
fn set_block_light(&mut self, x: i32, y: i32, z: i32, light: u8) {
2016-04-03 10:42:54 -04:00
let s_idx = y >> 4;
if s_idx < 0 || s_idx > 15 {
return;
}
2016-04-03 10:42:54 -04:00
let s_idx = s_idx as usize;
if self.sections[s_idx].is_none() {
if light == 0 {
return;
}
let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none());
self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky));
}
if let Some(sec) = self.sections[s_idx].as_mut() {
sec.set_block_light(x, y & 0xF, z, light)
}
}
fn get_sky_light(&self, x: i32, y: i32, z: i32) -> u8 {
let s_idx = y >> 4;
if s_idx < 0 || s_idx > 15 {
return 15;
}
match self.sections[s_idx as usize].as_ref() {
Some(sec) => sec.get_sky_light(x, y & 0xF, z),
None => 15,
}
}
fn set_sky_light(&mut self, x: i32, y: i32, z: i32, light: u8) {
2016-04-03 10:42:54 -04:00
let s_idx = y >> 4;
if s_idx < 0 || s_idx > 15 {
return;
}
2016-04-03 10:42:54 -04:00
let s_idx = s_idx as usize;
if self.sections[s_idx].is_none() {
if light == 15 {
return;
}
let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none());
self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky));
}
if let Some(sec) = self.sections[s_idx as usize].as_mut() {
sec.set_sky_light(x, y & 0xF, z, light)
}
}
2016-03-24 15:20:26 -04:00
fn get_biome(&self, x: i32, z: i32) -> biome::Biome {
biome::Biome::by_id(self.biomes[((z << 4) | x) as usize] as usize)
2016-03-24 15:20:26 -04:00
}
2016-03-18 18:24:30 -04:00
}
2016-03-24 19:27:22 -04:00
pub struct Section {
pub cull_info: chunk_builder::CullInfo,
2016-03-24 17:13:24 -04:00
pub render_buffer: render::ChunkBuffer,
2016-03-24 19:27:22 -04:00
2016-03-18 18:24:30 -04:00
y: u8,
blocks: storage::BlockStorage,
2016-03-18 18:24:30 -04:00
block_light: nibble::Array,
sky_light: nibble::Array,
dirty: bool,
2016-03-19 12:32:13 -04:00
building: bool,
2016-03-18 18:24:30 -04:00
}
impl Section {
fn new(y: u8, fill_sky: bool) -> Section {
2016-03-18 18:24:30 -04:00
let mut section = Section {
2016-03-24 19:27:22 -04:00
cull_info: chunk_builder::CullInfo::all_vis(),
2016-03-24 17:13:24 -04:00
render_buffer: render::ChunkBuffer::new(),
y,
2016-03-18 18:24:30 -04:00
blocks: storage::BlockStorage::new(4096),
2016-03-18 18:24:30 -04:00
block_light: nibble::Array::new(16 * 16 * 16),
sky_light: nibble::Array::new(16 * 16 * 16),
dirty: false,
2016-03-19 12:32:13 -04:00
building: false,
2016-03-18 18:24:30 -04:00
};
if fill_sky {
for i in 0..16 * 16 * 16 {
section.sky_light.set(i, 0xF);
}
2016-03-18 18:24:30 -04:00
}
section
}
2016-03-23 17:07:49 -04:00
fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block {
self.blocks.get(((y << 8) | (z << 4) | x) as usize)
2016-03-18 18:24:30 -04:00
}
fn set_block(&mut self, x: i32, y: i32, z: i32, b: block::Block) -> bool {
if self.blocks.set(((y << 8) | (z << 4) | x) as usize, b) {
self.dirty = true;
self.set_sky_light(x, y, z, 0);
self.set_block_light(x, y, z, 0);
true
} else {
false
}
2016-03-18 18:24:30 -04:00
}
fn get_block_light(&self, x: i32, y: i32, z: i32) -> u8 {
self.block_light.get(((y << 8) | (z << 4) | x) as usize)
}
fn set_block_light(&mut self, x: i32, y: i32, z: i32, l: u8) {
self.block_light.set(((y << 8) | (z << 4) | x) as usize, l);
}
fn get_sky_light(&self, x: i32, y: i32, z: i32) -> u8 {
self.sky_light.get(((y << 8) | (z << 4) | x) as usize)
}
fn set_sky_light(&mut self, x: i32, y: i32, z: i32, l: u8) {
self.sky_light.set(((y << 8) | (z << 4) | x) as usize, l);
}
}