stevenarella/src/world/mod.rs

1878 lines
62 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;
use steven_protocol::protocol::LenPrefixed;
use steven_protocol::protocol::Serializable;
use steven_protocol::protocol::VarInt;
use steven_protocol::types::bit;
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;
2022-09-17 21:07:59 -04:00
use crate::types::nibble;
use byteorder::ReadBytesExt;
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 log::info;
use std::cmp::Ordering;
2022-10-24 05:21:33 -04:00
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::convert::TryInto;
use std::hash::BuildHasherDefault;
use std::io::Cursor;
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>>,
min_y: i32,
2022-09-17 21:07:59 -04:00
height: i32,
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>,
blocks: versioned block states, fixes world on fire #467 (#469) Since the unflattening in 1.13.x, block IDs are no longer stable across versions, and can be shifted by the addition of new block states. To get the right block IDs across multiple protocol versions, add a new `offsets` token to `define_blocks!`, which is similar to `offset` (used post-flattening, compare to `data` used pre-flattening), but accepts a protocol_version argument to enable block states _per-version_: * Add 'offsets' for protocol_version-specific blockstates As part of this change, by_vanilla_id is now a method of a VanillaIDMap instance, instead of a method of Block, so it can know the protocol version. Previously, the ID map was lazily computed statically, once, but this change allows it to be computed based on protocol version: * Move by_vanilla_id to VanillaIDMap instance Tools to help debug blocks: * Add DEBUG_BLOCKS environment variable to dump block states * Add dump_block command-line tool The block `offset`s were previously only correct for 1.13.2, to take advantage of the new version-specific `offsets` capability, blocks were updated for 1.14.x: 1.14+ (protocol_version >= 477): * Add NoteBlock instruments * Add FlowerPot and RedFlowerVariant cornflower, wither rose, lily of the valley * Add StandingSign wood variants * Add WallSign tree variants * Add StoneSlab smooth stone, cut sandstone, cut red sandstone This fixes #467, where grass was misinterpreted as fire on 1.14+ because of the ID shifts caused by NoteBlock, among other block misassignments (though not 100%).
2021-01-13 22:50:05 -05:00
pub id_map: block::VanillaIDMap,
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)]
2022-09-17 21:07:59 -04:00
pub 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 {
blocks: versioned block states, fixes world on fire #467 (#469) Since the unflattening in 1.13.x, block IDs are no longer stable across versions, and can be shifted by the addition of new block states. To get the right block IDs across multiple protocol versions, add a new `offsets` token to `define_blocks!`, which is similar to `offset` (used post-flattening, compare to `data` used pre-flattening), but accepts a protocol_version argument to enable block states _per-version_: * Add 'offsets' for protocol_version-specific blockstates As part of this change, by_vanilla_id is now a method of a VanillaIDMap instance, instead of a method of Block, so it can know the protocol version. Previously, the ID map was lazily computed statically, once, but this change allows it to be computed based on protocol version: * Move by_vanilla_id to VanillaIDMap instance Tools to help debug blocks: * Add DEBUG_BLOCKS environment variable to dump block states * Add dump_block command-line tool The block `offset`s were previously only correct for 1.13.2, to take advantage of the new version-specific `offsets` capability, blocks were updated for 1.14.x: 1.14+ (protocol_version >= 477): * Add NoteBlock instruments * Add FlowerPot and RedFlowerVariant cornflower, wither rose, lily of the valley * Add StandingSign wood variants * Add WallSign tree variants * Add StoneSlab smooth stone, cut sandstone, cut red sandstone This fixes #467, where grass was misinterpreted as fire on 1.14+ because of the ID shifts caused by NoteBlock, among other block misassignments (though not 100%).
2021-01-13 22:50:05 -05:00
let id_map = block::VanillaIDMap::new(protocol_version);
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
World {
protocol_version,
blocks: versioned block states, fixes world on fire #467 (#469) Since the unflattening in 1.13.x, block IDs are no longer stable across versions, and can be shifted by the addition of new block states. To get the right block IDs across multiple protocol versions, add a new `offsets` token to `define_blocks!`, which is similar to `offset` (used post-flattening, compare to `data` used pre-flattening), but accepts a protocol_version argument to enable block states _per-version_: * Add 'offsets' for protocol_version-specific blockstates As part of this change, by_vanilla_id is now a method of a VanillaIDMap instance, instead of a method of Block, so it can know the protocol version. Previously, the ID map was lazily computed statically, once, but this change allows it to be computed based on protocol version: * Move by_vanilla_id to VanillaIDMap instance Tools to help debug blocks: * Add DEBUG_BLOCKS environment variable to dump block states * Add dump_block command-line tool The block `offset`s were previously only correct for 1.13.2, to take advantage of the new version-specific `offsets` capability, blocks were updated for 1.14.x: 1.14+ (protocol_version >= 477): * Add NoteBlock instruments * Add FlowerPot and RedFlowerVariant cornflower, wither rose, lily of the valley * Add StandingSign wood variants * Add WallSign tree variants * Add StoneSlab smooth stone, cut sandstone, cut red sandstone This fixes #467, where grass was misinterpreted as fire on 1.14+ because of the ID shifts caused by NoteBlock, among other block misassignments (though not 100%).
2021-01-13 22:50:05 -05:00
id_map,
2022-09-17 21:07:59 -04:00
height: 256,
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
..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 instant::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.get(&v.1).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.get_mut(&y) {
2016-03-24 19:27:22 -04:00
return Some(sec);
}
}
None
}
fn get_render_section_mut(
&mut self,
x: i32,
y: i32,
z: i32,
) -> Option<(Option<&mut Section>, &mut u32)> {
if !(0..=15).contains(&y) {
2016-03-24 19:27:22 -04:00
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];
if let Some(sec) = chunk.sections.get_mut(&y) {
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() {
for (y, sec) in &mut chunk.sections {
if !sec.building && sec.dirty {
out.push((chunk.position.0, *y, 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) {
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.get(&pos.1) {
2016-03-24 19:27:22 -04:00
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.get_mut(&pos.1) {
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.get_mut(&pos.1) {
2016-03-19 12:32:13 -04:00
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() {
for sec in chunk.sections.values_mut() {
sec.dirty = true;
2016-03-19 13:34:12 -04:00
}
}
}
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 {
if !(0..=15).contains(&cy) {
2016-03-19 12:32:13 -04:00
continue;
}
let section = chunk.sections.get(&cy);
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
}
fn dirty_chunks_by_bitmask(&mut self, x: i32, z: i32, mask: u64, num_sections: usize) {
for i in 0..num_sections {
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);
}
let i: i32 = i.try_into().unwrap();
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.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
let cpos = CPos(x, z);
{
if new {
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.chunks.insert(cpos, Chunk::new(cpos));
} else if !self.chunks.contains_key(&cpos) {
return Ok(());
}
let chunk = self.chunks.get_mut(&cpos).unwrap();
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 {
2022-10-24 05:21:33 -04:00
let fill_sky = Self::should_fill_sky(i, chunk, mask as u64);
if let Entry::Vacant(e) = chunk.sections.entry(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
if !fill_sky || mask & (1 << i) != 0 {
2022-10-24 05:21:33 -04:00
e.insert(Section::new(fill_sky));
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.get_mut(&i).unwrap();
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
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,
blocks: versioned block states, fixes world on fire #467 (#469) Since the unflattening in 1.13.x, block IDs are no longer stable across versions, and can be shifted by the addition of new block states. To get the right block IDs across multiple protocol versions, add a new `offsets` token to `define_blocks!`, which is similar to `offset` (used post-flattening, compare to `data` used pre-flattening), but accepts a protocol_version argument to enable block states _per-version_: * Add 'offsets' for protocol_version-specific blockstates As part of this change, by_vanilla_id is now a method of a VanillaIDMap instance, instead of a method of Block, so it can know the protocol version. Previously, the ID map was lazily computed statically, once, but this change allows it to be computed based on protocol version: * Move by_vanilla_id to VanillaIDMap instance Tools to help debug blocks: * Add DEBUG_BLOCKS environment variable to dump block states * Add dump_block command-line tool The block `offset`s were previously only correct for 1.13.2, to take advantage of the new version-specific `offsets` capability, blocks were updated for 1.14.x: 1.14+ (protocol_version >= 477): * Add NoteBlock instruments * Add FlowerPot and RedFlowerVariant cornflower, wither rose, lily of the valley * Add StandingSign wood variants * Add WallSign tree variants * Add StoneSlab smooth stone, cut sandstone, cut red sandstone This fixes #467, where grass was misinterpreted as fire on 1.14+ because of the ID shifts caused by NoteBlock, among other block misassignments (though not 100%).
2021-01-13 22:50:05 -05:00
self.id_map
.by_vanilla_id(id as usize, &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.get_mut(&i).unwrap();
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
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.get_mut(&i).unwrap();
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
data.read_exact(&mut section.sky_light.data)?;
}
if new {
data.read_exact(&mut chunk.biomes)?;
}
chunk.calculate_heightmap();
}
self.dirty_chunks_by_bitmask(x, z, mask.into(), 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
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 {
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);
{
if new {
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.chunks.insert(cpos, Chunk::new(cpos));
} else if !self.chunks.contains_key(&cpos) {
return Ok(());
}
let chunk = self.chunks.get_mut(&cpos).unwrap();
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 type array - whole byte per block
let mut block_types = [[0u8; 4096]; 16];
for i in 0..16 {
2022-10-24 05:21:33 -04:00
let fill_sky = Self::should_fill_sky(i, chunk, mask as u64);
if let Entry::Vacant(e) = chunk.sections.entry(i) {
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 !fill_sky || mask & (1 << i) != 0 {
2022-10-24 05:21:33 -04:00
e.insert(Section::new(fill_sky));
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.get_mut(&i).unwrap();
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
section.dirty = true;
data.read_exact(&mut block_types[i as usize])?;
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.get_mut(&i).unwrap();
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
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.get_mut(&i).unwrap();
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
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.get_mut(&(i as i32)).unwrap();
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 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,
blocks: versioned block states, fixes world on fire #467 (#469) Since the unflattening in 1.13.x, block IDs are no longer stable across versions, and can be shifted by the addition of new block states. To get the right block IDs across multiple protocol versions, add a new `offsets` token to `define_blocks!`, which is similar to `offset` (used post-flattening, compare to `data` used pre-flattening), but accepts a protocol_version argument to enable block states _per-version_: * Add 'offsets' for protocol_version-specific blockstates As part of this change, by_vanilla_id is now a method of a VanillaIDMap instance, instead of a method of Block, so it can know the protocol version. Previously, the ID map was lazily computed statically, once, but this change allows it to be computed based on protocol version: * Move by_vanilla_id to VanillaIDMap instance Tools to help debug blocks: * Add DEBUG_BLOCKS environment variable to dump block states * Add dump_block command-line tool The block `offset`s were previously only correct for 1.13.2, to take advantage of the new version-specific `offsets` capability, blocks were updated for 1.14.x: 1.14+ (protocol_version >= 477): * Add NoteBlock instruments * Add FlowerPot and RedFlowerVariant cornflower, wither rose, lily of the valley * Add StandingSign wood variants * Add WallSign tree variants * Add StoneSlab smooth stone, cut sandstone, cut red sandstone This fixes #467, where grass was misinterpreted as fire on 1.14+ because of the ID shifts caused by NoteBlock, among other block misassignments (though not 100%).
2021-01-13 22:50:05 -05:00
self.id_map
.by_vanilla_id(id as usize, &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.into(), 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
Ok(())
}
pub fn load_chunk19(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u16,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
2022-09-17 21:07:59 -04:00
self.load_chunk19_to_118(true, x, z, new, mask.into(), 16, data)
}
pub fn load_chunk115(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u16,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
2022-09-17 21:07:59 -04:00
self.load_chunk19_to_118(false, x, z, new, mask.into(), 16, data)
}
pub fn load_chunk117(
&mut self,
x: i32,
z: i32,
new: bool,
mask: u64,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
2022-09-17 21:07:59 -04:00
let num_sections = (self.height >> 4) as usize;
self.load_chunk19_to_118(false, x, z, new, mask, num_sections, data)
}
pub fn load_chunk118(
&mut self,
x: i32,
z: i32,
new: bool,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
let num_sections = (self.height >> 4) as usize;
let mut mask = 0;
for _ in 0..num_sections {
mask = (mask << 1) | 1;
}
self.load_chunk19_to_118(false, x, z, new, mask, num_sections, data)
}
pub fn load_dimension_type(&mut self, dimension_tags: Option<crate::nbt::NamedTag>) {
if let Some(crate::nbt::NamedTag(_, crate::nbt::Tag::Compound(tags))) = dimension_tags {
info!("Dimension type: {:?}", tags);
if let Some(crate::nbt::Tag::Int(min_y)) = tags.get("min_y") {
self.min_y = *min_y;
}
2022-09-17 21:07:59 -04:00
if let Some(crate::nbt::Tag::Int(height)) = tags.get("height") {
self.height = *height;
}
// TODO: More tags https://wiki.vg/Protocol#Login_.28play.29
}
}
#[allow(clippy::or_fun_call)]
2022-09-17 21:07:59 -04:00
fn load_chunk19_to_118(
&mut self,
read_biomes: bool,
x: i32,
z: i32,
new: bool,
mask: u64,
num_sections: usize,
data: Vec<u8>,
) -> Result<(), protocol::Error> {
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
{
if new {
2016-03-21 12:36:50 -04:00
self.chunks.insert(cpos, Chunk::new(cpos));
} else if !self.chunks.contains_key(&cpos) {
return Ok(());
}
let chunk = self.chunks.get_mut(&cpos).unwrap();
2016-03-21 10:05:13 -04:00
for i1 in 0..num_sections as i32 {
2022-09-17 21:07:59 -04:00
// Convert the section index to the chunk section's position,
// including negative values.
let i: i32 = (i1 as i32) + (self.min_y >> 4);
// Skip this chunk section if not in the mask bitmap.
if mask & (1 << i1) == 0 {
continue;
}
2022-09-17 21:07:59 -04:00
// Populate the section in this chunk if not already present.
let fill_sky = Self::should_fill_sky(i1, chunk, mask as u64);
2022-10-24 05:21:33 -04:00
let section = chunk
.sections
.entry(i)
2022-09-17 21:07:59 -04:00
.or_insert_with(|| Section::new(fill_sky));
section.dirty = true;
if self.protocol_version >= 451 {
let _block_count = data.read_u16::<byteorder::LittleEndian>()?;
// TODO: use block_count, "The client will keep count of the blocks as they are
// broken and placed, and, if the block count reaches 0, the whole chunk
// section is not rendered, even if it still has blocks." per https://wiki.vg/Chunk_Format#Data_structure
}
2016-03-21 12:36:50 -04:00
2022-10-24 05:21:33 -04:00
let palette =
PaletteParser::new(self.protocol_version, PaletteKind::BlockStates, &mut data)
.parse()?;
SectionParser::new(
self.protocol_version,
palette,
&self.id_map,
&self.modded_block_ids,
&mut data,
section,
)
.parse()?;
2016-03-21 12:36:50 -04:00
for bi in 0..4096 {
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
}
// Version 1.18+
if self.protocol_version >= 757 {
2022-10-24 05:21:33 -04:00
let _palette =
PaletteParser::new(self.protocol_version, PaletteKind::Biomes, &mut data)
.parse()?;
let _bits = LenPrefixed::<VarInt, u64>::read_from(&mut data)?.data;
// TODO: Use biome data
2022-10-24 05:21:33 -04:00
// Version 1.14 - 1.17
} else 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 {
2022-09-17 21:07:59 -04:00
if self.protocol_version > 340 {
for i in 0..256 {
chunk.biomes[i] = data.read_i32::<byteorder::BigEndian>()? as u8;
}
} else {
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
self.dirty_chunks_by_bitmask(x, z, mask, num_sections);
2022-09-17 21:07:59 -04:00
let mut remaining = Vec::new();
data.read_to_end(&mut remaining)?;
// The rest of the chunk data might be padded out with zeros.
// See https://bugs.mojang.com/browse/MC-131684.
2022-10-24 05:21:33 -04:00
assert!(
remaining.iter().all(|b| *b == 0),
"Failed to read all chunk data, had {} bytes left",
remaining.len()
);
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 !(0..=15).contains(&y) {
2016-03-21 12:36:50 -04:00
return;
}
let cpos = CPos(x, z);
if let Some(chunk) = self.chunks.get_mut(&cpos) {
if let Some(sec) = chunk.sections.get_mut(&y) {
2016-03-21 12:36:50 -04:00
sec.dirty = true;
2016-03-21 10:05:13 -04:00
}
}
}
2022-09-17 21:07:59 -04:00
/// Determine if we should fill the sky in this section based on already
/// existing chunks, and if we are expecting more chunks in the current
/// chunk data.
fn should_fill_sky(s_idx: i32, chunk: &Chunk, mask: u64) -> bool {
// Check if the chunk already contains previously loaded sections
// above this one.
if chunk.sections.keys().any(|s_idx2| *s_idx2 > s_idx) {
return false;
}
// Check if the chunk data we are currently reading is going to load
// another section above this one.
let above_mask = !((1 << s_idx) | ((1 << s_idx) - 1));
2022-10-24 05:21:33 -04:00
(mask & above_mask) == 0
2022-09-17 21:07:59 -04:00
}
2022-10-24 05:21:33 -04:00
pub fn set_light_data(
&mut self,
x: i32,
z: i32,
light_type: LightType,
masks: Vec<i64>,
data: Vec<LenPrefixed<VarInt, u8>>,
) {
2022-09-17 21:07:59 -04:00
let cpos = CPos(x, z);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
let mut data = data.iter();
2022-10-24 05:21:33 -04:00
for (i, mask) in masks.iter().enumerate() {
2022-09-17 21:07:59 -04:00
for j in 0..64 {
if mask & (1 << j) != 0 {
let new_light = &data.next().unwrap().data;
let s_idx = i as i32 * 64 + j + self.min_y - 1;
2022-10-24 05:21:33 -04:00
let section = chunk
.sections
.entry(s_idx)
.or_insert_with(|| Section::new(false));
2022-09-17 21:07:59 -04:00
let current_light = match light_type {
LightType::Block => &mut section.block_light,
LightType::Sky => &mut section.sky_light,
};
current_light.data.copy_from_slice(new_light);
}
}
}
}
pub fn clear_light_data(&mut self, x: i32, z: i32, light_type: LightType, masks: Vec<i64>) {
let chunk = match self.chunks.get_mut(&CPos(x, z)) {
Some(c) => c,
None => return,
};
2022-10-24 05:21:33 -04:00
for (i, mask) in masks.iter().enumerate() {
2022-09-17 21:07:59 -04:00
for j in 0..64 {
if mask & (1 << j) != 0 {
let s_idx = i as i32 * 64 + j + self.min_y - 1;
let section = match chunk.sections.get_mut(&s_idx) {
Some(s) => s,
None => return,
};
let current_light = match light_type {
LightType::Block => &mut section.block_light,
LightType::Sky => &mut section.sky_light,
};
current_light.data.copy_from_slice(&[0u8; 2048]);
}
}
}
}
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: HashMap<i32, Section>,
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: HashMap::new(),
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;
if !(0..=15).contains(&s_idx) {
return false;
2016-03-18 18:24:30 -04:00
}
if !self.sections.contains_key(&s_idx) {
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.keys().any(|s_idx2| *s_idx2 > s_idx);
self.sections.insert(s_idx, Section::new(fill_sky));
2016-03-18 18:24:30 -04:00
}
2016-04-01 15:00:13 -04:00
{
let section = self.sections.get_mut(&s_idx).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 !(0..=15).contains(&s_idx) {
return block::Missing {};
2016-03-18 18:24:30 -04:00
}
match self.sections.get(&s_idx) {
2016-03-18 18:24:30 -04:00
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 !(0..=15).contains(&s_idx) {
return 0;
}
match self.sections.get(&s_idx) {
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 !(0..=15).contains(&s_idx) {
return;
}
if !self.sections.contains_key(&s_idx) {
if light == 0 {
return;
}
let fill_sky = self.sections.keys().any(|s_idx2| *s_idx2 > s_idx);
self.sections.insert(s_idx, Section::new(fill_sky));
}
if let Some(sec) = self.sections.get_mut(&s_idx) {
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 !(0..=15).contains(&s_idx) {
return 15;
}
match self.sections.get(&s_idx) {
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 !(0..=15).contains(&s_idx) {
return;
}
if !self.sections.contains_key(&s_idx) {
if light == 15 {
return;
}
let fill_sky = self.sections.keys().any(|s_idx2| *s_idx2 > s_idx);
self.sections.insert(s_idx, Section::new(fill_sky));
}
if let Some(sec) = self.sections.get_mut(&s_idx) {
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
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(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(),
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);
}
}
/// The kind of palette we are reading. This can affect how we interpret bits
/// per entry which is different between block states and biomes.
#[derive(PartialEq)]
enum PaletteKind {
BlockStates,
Biomes,
}
/// These are the different formats the palette data can be interpreted as.
/// See https://wiki.vg/Chunk_Format#Palettes for more info.
enum PaletteFormat {
SingleValued(usize),
Indirect(Vec<usize>, u8),
Direct(u8),
}
/// A struct to manage building a palette that can be used to resolve block
/// states or biomes inside a chunk section.
struct PaletteParser<'a> {
protocol_version: i32,
kind: PaletteKind,
2022-10-24 05:21:33 -04:00
data: &'a mut Cursor<Vec<u8>>,
}
impl PaletteParser<'_> {
2022-10-24 05:21:33 -04:00
pub fn new(
protocol_version: i32,
kind: PaletteKind,
data: &mut Cursor<Vec<u8>>,
) -> PaletteParser<'_> {
if protocol_version < 757 && kind == PaletteKind::Biomes {
2022-10-24 05:21:33 -04:00
panic!(
"Protocol {} doesn't support biome palettes",
protocol_version
);
}
PaletteParser {
protocol_version,
kind,
data,
}
}
fn parse_single_valued_palette(&mut self) -> Result<PaletteFormat, protocol::Error> {
2022-10-24 05:21:33 -04:00
Ok(PaletteFormat::SingleValued(
VarInt::read_from(self.data)?.0 as usize,
))
}
2022-10-24 05:21:33 -04:00
fn parse_indirect_palette(
&mut self,
bits_per_entry: u8,
) -> Result<PaletteFormat, protocol::Error> {
let count = VarInt::read_from(self.data)?.0 as usize;
let mut mapping = Vec::with_capacity(count);
for _i in 0..count {
mapping.push(VarInt::read_from(self.data)?.0 as usize);
}
Ok(PaletteFormat::Indirect(mapping, bits_per_entry))
}
pub fn parse(mut self) -> Result<PaletteFormat, protocol::Error> {
let mut bits_per_entry = self.data.read_u8()?;
// Pre 1.18, when bits_per_entry == 0, it indicates we should use
// an indirect palette rather than the new single valued one. We are
// setting this to 4 since it's the minimum value for indirect
// palettes.
if self.protocol_version < 757 && bits_per_entry == 0 {
bits_per_entry = 4;
}
// Figure out how we should interpret the palette based on bits_per_entry.
Ok(match self.kind {
PaletteKind::BlockStates => match bits_per_entry {
0 => self.parse_single_valued_palette()?,
n if (1..9).contains(&n) => self.parse_indirect_palette(n.max(4))?,
n if (9..17).contains(&n) => PaletteFormat::Direct(n),
// https://wiki.vg/Chunk_Format#Data_structure "This increase can go up to 16 bits per block"...
2022-10-24 05:21:33 -04:00
n => panic!(
"PaletteParser::parse: block state bits_per_entry={} > 16",
n
),
},
PaletteKind::Biomes => match bits_per_entry {
0 => self.parse_single_valued_palette()?,
n if (1..4).contains(&n) => self.parse_indirect_palette(n)?,
n if (4..17).contains(&n) => PaletteFormat::Direct(n),
n => panic!("PaletteParser::parse: biome bits_per_entry={} > 16", n),
},
})
}
}
/// A struct to manage building a chunk section struct from a palette and the
/// data received from the server.
struct SectionParser<'a> {
protocol_version: i32,
palette: PaletteFormat,
id_map: &'a block::VanillaIDMap,
modded_block_ids: &'a HashMap<usize, String>,
data: &'a mut Cursor<Vec<u8>>,
2022-09-17 21:07:59 -04:00
section: &'a mut Section,
}
impl SectionParser<'_> {
pub fn new<'a>(
protocol_version: i32,
palette: PaletteFormat,
id_map: &'a block::VanillaIDMap,
modded_block_ids: &'a HashMap<usize, String>,
2022-09-17 21:07:59 -04:00
data: &'a mut Cursor<Vec<u8>>,
section: &'a mut Section,
) -> SectionParser<'a> {
SectionParser {
protocol_version,
palette,
id_map,
modded_block_ids,
data,
2022-09-17 21:07:59 -04:00
section,
}
}
2022-09-17 21:07:59 -04:00
pub fn parse(self) -> Result<(), protocol::Error> {
let bits = LenPrefixed::<VarInt, u64>::read_from(self.data)?.data;
let padded = self.protocol_version >= 735;
match self.palette {
PaletteFormat::SingleValued(id) => {
let block = self.id_map.by_vanilla_id(id, self.modded_block_ids);
for i in 0..4096 {
2022-09-17 21:07:59 -04:00
self.section.blocks.set(i, block);
}
2022-10-24 05:21:33 -04:00
}
PaletteFormat::Indirect(mapping, bits_per_entry) => {
let entries = bit::Map::from_raw(bits, bits_per_entry as usize, padded);
for i in 0..4096 {
let index = entries.get(i);
let id = *mapping.get(index).unwrap();
let block = self.id_map.by_vanilla_id(id, self.modded_block_ids);
2022-09-17 21:07:59 -04:00
self.section.blocks.set(i, block);
}
2022-10-24 05:21:33 -04:00
}
PaletteFormat::Direct(bits_per_entry) => {
let entries = bit::Map::from_raw(bits, bits_per_entry as usize, padded);
for i in 0..4096 {
let id = entries.get(i);
let block = self.id_map.by_vanilla_id(id, self.modded_block_ids);
2022-09-17 21:07:59 -04:00
self.section.blocks.set(i, block);
}
2022-10-24 05:21:33 -04:00
}
}
2022-09-17 21:07:59 -04:00
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_chunk_1_12_2() {
let mut world = World::new(340);
let chunk_data = std::fs::read("test/chunk_1.12.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, 7, 8, true, 63, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_13_2() {
let mut world = World::new(404);
let chunk_data = std::fs::read("test/chunk_1.13.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, -20, -7, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_18w50a() {
let mut world = World::new(451);
let chunk_data = std::fs::read("test/chunk_18w50a.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, -25, -18, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_19w02a() {
let mut world = World::new(452);
let chunk_data = std::fs::read("test/chunk_19w02a.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, -10, -26, true, 15, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_14() {
let mut world = World::new(477);
let chunk_data = std::fs::read("test/chunk_1.14.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, -14, 0, true, 63, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_14_1() {
let mut world = World::new(480);
let chunk_data = std::fs::read("test/chunk_1.14.1.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, 2, -25, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_14_2() {
let mut world = World::new(485);
let chunk_data = std::fs::read("test/chunk_1.14.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, 1, 5, true, 15, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_14_3() {
let mut world = World::new(490);
let chunk_data = std::fs::read("test/chunk_1.14.3.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, -9, -25, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_14_4() {
let mut world = World::new(498);
let chunk_data = std::fs::read("test/chunk_1.14.4.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(true, 2, -14, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_15_1() {
let mut world = World::new(575);
let chunk_data = std::fs::read("test/chunk_1.15.1.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -10, -10, true, 63, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_15_2() {
let mut world = World::new(578);
let chunk_data = std::fs::read("test/chunk_1.15.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -19, -18, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_16() {
let mut world = World::new(735);
let chunk_data = std::fs::read("test/chunk_1.16.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, 2, -26, true, 63, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_16_1() {
let mut world = World::new(736);
let chunk_data = std::fs::read("test/chunk_1.16.1.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -6, -5, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_16_2() {
let mut world = World::new(751);
let chunk_data = std::fs::read("test/chunk_1.16.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -22, -20, true, 15, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_16_3() {
let mut world = World::new(753);
let chunk_data = std::fs::read("test/chunk_1.16.3.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, 4, 2, true, 63, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_16_4() {
let mut world = World::new(754);
let chunk_data = std::fs::read("test/chunk_1.16.4.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -10, -8, true, 15, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_17_1() {
let mut world = World::new(756);
let chunk_data = std::fs::read("test/chunk_1.17.1.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -3, -25, true, 31, 16, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_18_1() {
let mut world = World::new(757);
let chunk_data = std::fs::read("test/chunk_1.18.1.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -14, -5, true, 0xffffff, 24, chunk_data)
.unwrap();
}
#[test]
fn parse_chunk_1_18_2() {
let mut world = World::new(758);
let chunk_data = std::fs::read("test/chunk_1.18.2.bin").unwrap();
2022-10-24 05:21:33 -04:00
world
.load_chunk19_to_118(false, -10, -8, true, 0xffffff, 24, chunk_data)
.unwrap();
}
2022-10-24 05:21:33 -04:00
}