GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Merge pull request #257 from feather-rs/block-entities · BuggStream/feather@3e7570e

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • Cargo.lock
  • Cargo.toml
  • codegen/src
    • lib.rs
  • core
    • anvil
      • Cargo.toml
      • src
        • block_entity.rs
        • entity.rs
        • lib.rs
        • player.rs
        • region
          • blob.rs
          • mod.rs
    • inventory/src
      • lib.rs
      • window.rs
    • network/src
      • packet.rs
      • packets.rs
  • data
    • lock
  • server
    • Cargo.toml
    • README.md
    • block
      • Cargo.toml
      • src
        • chest.rs
        • init.rs
        • lib.rs
    • chunk/src
      • chunk_manager.rs
      • chunk_worker.rs
      • save.rs
    • entity/src
      • broadcasters
        • entity_deletion.rs
        • inventory.rs
      • object
        • item.rs
    • player
      • Cargo.toml
      • src
        • death.rs
        • lib.rs
        • packet_handlers.rs
        • packet_handlers
          • block_interaction
            • crafting_table.rs
            • mod.rs
          • digging.rs
          • inventory.rs
          • placement.rs
          • window.rs
    • src
      • event_handlers.rs
      • init.rs
      • systems.rs
    • test/src
      • unit.rs
    • types/src
      • components
        • marker.rs
        • serialize.rs
      • events.rs
      • game.rs
      • misc.rs
    • util/src
      • load.rs

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎Cargo.lock‎

Copy file name to clipboardExpand all lines: Cargo.lock
+25-15Lines changed: 25 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎Cargo.toml‎

Copy file name to clipboardExpand all lines: Cargo.toml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ members = [
2525

2626
"server",
2727
"server/template",
28+
"server/block",
2829
"server/chat",
2930
"server/chunk",
3031
"server/commands",
Collapse file

‎codegen/src/lib.rs‎

Copy file name to clipboardExpand all lines: codegen/src/lib.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ lazy_static! {
7676
m.insert("f32", PacketParameterType::F32);
7777
m.insert("f64", PacketParameterType::F64);
7878
m.insert("Uuid", PacketParameterType::Uuid);
79-
m.insert("NbtTag", PacketParameterType::Nbt);
79+
m.insert("Blob", PacketParameterType::Nbt);
8080
m.insert("Slot", PacketParameterType::Slot);
8181
m.insert("EntityMetadata", PacketParameterType::EntityMetadata);
8282

Collapse file

‎core/anvil/Cargo.toml‎

Copy file name to clipboardExpand all lines: core/anvil/Cargo.toml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ thiserror = "1.0"
1616
tokio = { version = "0.2", features = ["full"] }
1717
serde = "1.0"
1818
uuid = "0.8"
19-
hematite-nbt = { git = "https://github.com/feather-rs/hematite_nbt" }
19+
hematite-nbt = "0.4"
2020
byteorder = "1.3"
2121
bitvec = "0.17"
2222
anyhow = "1.0"
Collapse file

‎core/anvil/src/block_entity.rs‎

Copy file name to clipboard
+191Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
use crate::player::InventorySlot;
2+
use nbt::Value;
3+
use serde::{Deserialize, Serialize};
4+
use std::collections::HashMap;
5+
6+
/// A block entity loaded or saved to the Anvil format.
7+
/// Should be serialized using NBT.
8+
///
9+
/// https://minecraft.gamepedia.com/Chunk_format#Block_entity_format
10+
#[derive(Debug, Clone, Serialize, Deserialize)]
11+
pub struct BlockEntityData {
12+
#[serde(flatten)]
13+
pub base: BlockEntityBase,
14+
#[serde(flatten)]
15+
pub kind: BlockEntityKind,
16+
}
17+
18+
impl BlockEntityData {
19+
pub fn into_nbt_value(self) -> Value {
20+
let mut compound = HashMap::new();
21+
22+
compound.insert(String::from("x"), Value::Int(self.base.x));
23+
compound.insert(String::from("y"), Value::Int(self.base.y));
24+
compound.insert(String::from("z"), Value::Int(self.base.z));
25+
26+
let id = match self.kind {
27+
BlockEntityKind::Chest { items, .. } => {
28+
compound.insert(
29+
String::from("Items"),
30+
Value::List(
31+
items
32+
.into_iter()
33+
.map(InventorySlot::into_nbt_value)
34+
.collect(),
35+
),
36+
);
37+
"minecraft:chest"
38+
}
39+
_ => todo!("implement block entity into_nbt_value"),
40+
};
41+
compound.insert(String::from("id"), Value::String(String::from(id)));
42+
43+
Value::Compound(compound)
44+
}
45+
}
46+
47+
/// Data common to all block entities.
48+
#[derive(Debug, Clone, Serialize, Deserialize)]
49+
pub struct BlockEntityBase {
50+
/// X coordinate in global coordinate space.
51+
pub x: i32,
52+
/// Y coordinate in global space.
53+
pub y: i32,
54+
/// Z coordinate in global space.
55+
pub z: i32,
56+
}
57+
58+
/// Kind of a block entity.
59+
#[derive(Debug, Clone, Serialize, Deserialize)]
60+
#[serde(tag = "id")]
61+
#[serde(rename_all = "PascalCase")]
62+
pub enum BlockEntityKind {
63+
#[serde(rename = "minecraft:beacon")]
64+
Beacon {
65+
levels: i32,
66+
primary: i32,
67+
secondary: i32,
68+
},
69+
#[serde(rename = "minecraft:bed")]
70+
Bed, // empty in JE
71+
#[serde(rename = "minecraft:brewing_stand")]
72+
BrewingStand {
73+
items: Vec<InventorySlot>,
74+
brew_time: i16,
75+
fuel: i8,
76+
},
77+
#[serde(rename = "minecraft:cauldron")]
78+
Cauldron {
79+
items: Vec<InventorySlot>,
80+
potion_id: i16,
81+
splash_potion: bool,
82+
is_movable: bool,
83+
},
84+
#[serde(rename = "minecraft:chest")]
85+
Chest {
86+
#[serde(rename = "Items")]
87+
items: Vec<InventorySlot>,
88+
loot_table: Option<String>,
89+
loot_table_seed: Option<i64>,
90+
},
91+
#[serde(rename = "minecraft:comparator")]
92+
Comparator { output_signal: i32 },
93+
#[serde(rename = "minecraft:command_block")]
94+
CommandBlock {
95+
custom_name: Option<String>,
96+
command: String,
97+
success_count: i32,
98+
last_output: String,
99+
track_output: bool,
100+
powered: bool,
101+
auto: bool,
102+
condition_met: bool,
103+
update_last_execution: bool,
104+
last_execution: i64,
105+
},
106+
#[serde(rename = "minecraft:daylight_detector")]
107+
DaylightDetector, // empty
108+
#[serde(rename = "minecraft:dispenser")]
109+
Dispenser { items: Vec<InventorySlot> },
110+
#[serde(rename = "minecraft:dropper")]
111+
Dropper { items: Vec<InventorySlot> },
112+
#[serde(rename = "minecraft:enchanting_table")]
113+
EnchantingTable,
114+
#[serde(rename = "minecraft:ender_chest")]
115+
EnderChest,
116+
#[serde(rename = "minecraft:end_gateway")]
117+
EndGateway { age: i64, exact_teleport: bool },
118+
#[serde(rename = "minecraft:end_portal")]
119+
EndPortal,
120+
#[serde(rename = "minecraft:furnace")]
121+
Furnace {
122+
items: Vec<InventorySlot>,
123+
burn_time: i16,
124+
cook_time: i16,
125+
cook_time_total: i16,
126+
},
127+
#[serde(rename = "minecraft:hopper")]
128+
Hopper {
129+
items: Vec<InventorySlot>,
130+
transfer_cooldown: i32,
131+
},
132+
#[serde(rename = "minecraft:jigsaw")]
133+
Jigsaw {
134+
target_pool: String,
135+
final_state: String,
136+
/// spelled "attachement" on the wiki,
137+
/// but mispelling is probably a mistake?
138+
attachment_type: String,
139+
},
140+
#[serde(rename = "minecraft:jukebox")]
141+
Jukebox { record_item: InventorySlot },
142+
// TODO: a few more
143+
}
144+
145+
impl BlockEntityKind {
146+
pub fn variant(&self) -> BlockEntityVariant {
147+
match self {
148+
BlockEntityKind::Beacon { .. } => BlockEntityVariant::Beacon,
149+
BlockEntityKind::Bed { .. } => BlockEntityVariant::Bed,
150+
BlockEntityKind::BrewingStand { .. } => BlockEntityVariant::BrewingStand,
151+
BlockEntityKind::Cauldron { .. } => BlockEntityVariant::Cauldron,
152+
BlockEntityKind::Comparator { .. } => BlockEntityVariant::Comparator,
153+
BlockEntityKind::CommandBlock { .. } => BlockEntityVariant::CommandBlock,
154+
BlockEntityKind::Chest { .. } => BlockEntityVariant::Chest,
155+
BlockEntityKind::DaylightDetector { .. } => BlockEntityVariant::DaylightDetector,
156+
BlockEntityKind::Dispenser { .. } => BlockEntityVariant::Dispenser,
157+
BlockEntityKind::Dropper { .. } => BlockEntityVariant::Dropper,
158+
BlockEntityKind::EnchantingTable { .. } => BlockEntityVariant::EnchantingTable,
159+
BlockEntityKind::EnderChest { .. } => BlockEntityVariant::EnderChest,
160+
BlockEntityKind::EndGateway { .. } => BlockEntityVariant::EndGateway,
161+
BlockEntityKind::EndPortal { .. } => BlockEntityVariant::EndPortal,
162+
BlockEntityKind::Furnace { .. } => BlockEntityVariant::Furnace,
163+
BlockEntityKind::Hopper { .. } => BlockEntityVariant::Hopper,
164+
BlockEntityKind::Jigsaw { .. } => BlockEntityVariant::Jigsaw,
165+
BlockEntityKind::Jukebox { .. } => BlockEntityVariant::Jukebox,
166+
}
167+
}
168+
}
169+
170+
/// Variant of a `BlockEntityKind`.
171+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
172+
pub enum BlockEntityVariant {
173+
Beacon,
174+
Bed,
175+
BrewingStand,
176+
Cauldron,
177+
Chest,
178+
Comparator,
179+
CommandBlock,
180+
DaylightDetector,
181+
Dispenser,
182+
Dropper,
183+
EnchantingTable,
184+
EnderChest,
185+
EndGateway,
186+
EndPortal,
187+
Furnace,
188+
Hopper,
189+
Jigsaw,
190+
Jukebox,
191+
}
Collapse file

‎core/anvil/src/entity.rs‎

Copy file name to clipboardExpand all lines: core/anvil/src/entity.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ impl BaseEntityData {
149149
String::from("Motion"),
150150
Value::List(self.velocity.iter().copied().map(Value::Double).collect()),
151151
);
152+
map.insert(String::from("Health"), Value::Float(self.health));
152153
}
153154
}
154155

Collapse file

‎core/anvil/src/lib.rs‎

Copy file name to clipboardExpand all lines: core/anvil/src/lib.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! world saves. Currently includes region file loading,
33
//! player data loading, and level data loading.
44
5+
pub mod block_entity;
56
pub mod entity;
67
pub mod level;
78
pub mod player;
Collapse file

‎core/anvil/src/player.rs‎

Copy file name to clipboardExpand all lines: core/anvil/src/player.rs
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ use feather_inventory::player_constants::{
44
SLOT_INVENTORY_OFFSET, SLOT_OFFHAND,
55
};
66
use feather_items::{Item, ItemStack};
7+
use nbt::Value;
78
use serde::{Deserialize, Serialize};
8-
use std::path::{Path, PathBuf};
9+
use std::{
10+
collections::HashMap,
11+
path::{Path, PathBuf},
12+
};
913
use tokio::io::AsyncWriteExt;
1014
use tokio::prelude::{AsyncRead, AsyncWrite};
1115
use uuid::Uuid;
@@ -88,6 +92,16 @@ impl InventorySlot {
8892
None
8993
}
9094
}
95+
96+
pub fn into_nbt_value(self) -> Value {
97+
let mut compound = HashMap::new();
98+
99+
compound.insert(String::from("Count"), Value::Byte(self.count));
100+
compound.insert(String::from("id"), Value::String(self.item));
101+
compound.insert(String::from("Slot"), Value::Byte(self.slot));
102+
103+
Value::Compound(compound)
104+
}
91105
}
92106

93107
async fn load_from_file<R: AsyncRead + Unpin>(mut reader: R) -> Result<PlayerData, nbt::Error> {
Collapse file

‎core/anvil/src/region/blob.rs‎

Copy file name to clipboardExpand all lines: core/anvil/src/region/blob.rs
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ fn level_to_value(level: ChunkLevel) -> Value {
7777
entities.push(entity.into_nbt_value());
7878
});
7979

80+
let mut block_entities = Vec::with_capacity(level.block_entities.len());
81+
level.block_entities.into_iter().for_each(|entity| {
82+
block_entities.push(entity.into_nbt_value());
83+
});
84+
8085
map.insert(String::from("Entities"), Value::List(entities));
86+
map.insert(String::from("TileEntities"), Value::List(block_entities));
8187

8288
Value::Compound(map)
8389
}
@@ -150,6 +156,7 @@ mod tests {
150156
}],
151157
biomes: vec![10],
152158
entities: vec![],
159+
block_entities: vec![],
153160
heightmaps: vec![],
154161
},
155162
};

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.