From 5bd7fccbe3efb43a17d384ca1610693095b4285d Mon Sep 17 00:00:00 2001 From: nakul-py Date: Sat, 4 Jan 2025 18:51:45 +0530 Subject: [PATCH] Addning inventory to the level crate --- crates/level/Cargo.toml | 1 + .../level/src/level/db_interface/inventory.rs | 12 ++++ .../level/src/level/db_interface/key_level.rs | 3 - crates/level/src/level/db_interface/mod.rs | 1 + crates/level/src/level/db_interface/rusty.rs | 56 ++++++++++++++++++- 5 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 crates/level/src/level/db_interface/inventory.rs diff --git a/crates/level/Cargo.toml b/crates/level/Cargo.toml index d16d195c..c0106cc8 100644 --- a/crates/level/Cargo.toml +++ b/crates/level/Cargo.toml @@ -19,6 +19,7 @@ serde = "1.x.x" rusty-leveldb = "3.x.x" miniz_oxide = "0.x.x" vek = "0.17" +bincode = "1.3" [dev-dependencies] rand = "0.8" diff --git a/crates/level/src/level/db_interface/inventory.rs b/crates/level/src/level/db_interface/inventory.rs new file mode 100644 index 00000000..133083f2 --- /dev/null +++ b/crates/level/src/level/db_interface/inventory.rs @@ -0,0 +1,12 @@ +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize)] +pub struct InventoryData { + pub items: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct InventoryItem { + pub id: u32, + pub quantity: u32, +} diff --git a/crates/level/src/level/db_interface/key_level.rs b/crates/level/src/level/db_interface/key_level.rs index 05d36de7..9c2d44a0 100644 --- a/crates/level/src/level/db_interface/key_level.rs +++ b/crates/level/src/level/db_interface/key_level.rs @@ -53,8 +53,6 @@ pub enum KeyTypeTag { ActorDigestVersion = 65, // 41 "A" Actor digest version - Inventory = 66, // 42 "B" Inventories - LegacyVersion = 118, // 76 "v" 1 byte; moved to Version in v1.16.100 } @@ -83,7 +81,6 @@ impl KeyTypeTag { 63 => Some(KeyTypeTag::BlendingBiomeHeight), 64 => Some(KeyTypeTag::BlendingData), 65 => Some(KeyTypeTag::ActorDigestVersion), - 66 => Some(KeyTypeTag::Inventory), 118 => Some(KeyTypeTag::LegacyVersion), _ => None, } diff --git a/crates/level/src/level/db_interface/mod.rs b/crates/level/src/level/db_interface/mod.rs index cd74e340..29e7d976 100644 --- a/crates/level/src/level/db_interface/mod.rs +++ b/crates/level/src/level/db_interface/mod.rs @@ -2,3 +2,4 @@ pub mod bedrock_key; pub mod db; pub mod key_level; pub mod rusty; +pub mod inventory; diff --git a/crates/level/src/level/db_interface/rusty.rs b/crates/level/src/level/db_interface/rusty.rs index 4ee00137..deeb8310 100644 --- a/crates/level/src/level/db_interface/rusty.rs +++ b/crates/level/src/level/db_interface/rusty.rs @@ -2,6 +2,8 @@ use crate::level::db_interface::bedrock_key::ChunkKey; use crate::level::db_interface::db::LevelDBKey; use crate::level::db_interface::key_level::KeyTypeTag; use crate::level::file_interface::RawWorldTrait; +use crate::level::db_interface::inventory::InventoryData; +use crate::level::db_interface::inventory::InventoryItem; use bedrockrs_shared::world::dimension::Dimension; use byteorder::{LittleEndian, ReadBytesExt}; use miniz_oxide::deflate::{compress_to_vec, compress_to_vec_zlib, CompressionLevel}; @@ -74,6 +76,7 @@ const COMPRESSION_LEVEL: u8 = CompressionLevel::DefaultLevel as u8; pub struct RustyDBInterface { db: DB, phantom_data: PhantomData, + user_state: UserState, } #[derive(Debug, Error)] @@ -113,6 +116,56 @@ impl RustyDBInterface { } } +impl RustyDBInterface { + pub fn save_inventory( + &mut self, + chunk_key: &ChunkKey, + inventory: &InventoryData, + ) -> Result<(), DBError> { + let user_state = &mut self.user_state; + let serialized_inventory = bincode::serialize(inventory).map_err(|e| DBError::DatabaseError(Status { + code: rusty_leveldb::StatusCode::Corruption, + err: e.to_string(), + }))?; + let user_state = &mut self.user_state; + self.set_subchunk_raw(*chunk_key, &serialized_inventory, &mut self.user_state) + } + + pub fn load_inventory(&mut self, chunk_key: &ChunkKey) -> Result, DBError> { + if let Some(data) = self.get_subchunk_raw(*chunk_key, &mut self.user_state)? { + let inventory: InventoryData = bincode::deserialize(&data).map_err(|e| DBError::DatabaseError(Status { + code: rusty_leveldb::StatusCode::Corruption, + err: e.to_string(), + }))?; + Ok(Some(inventory)) + } else { + Ok(None) + } + } + + pub fn add_item_to_inventory( + &mut self, + chunk_key: &ChunkKey, + item: InventoryItem, + ) -> Result<(), DBError> { + let mut inventory = self.load_inventory(chunk_key)?.unwrap_or(InventoryData { items: vec![] }); + inventory.items.push(item); + self.save_inventory(chunk_key, &inventory) + } + + pub fn remove_item_from_inventory( + &mut self, + chunk_key: &ChunkKey, + item_id: u32, + ) -> Result<(), DBError> { + if let Some(mut inventory) = self.load_inventory(chunk_key)? { + inventory.items.retain(|item| item.id != item_id); + self.save_inventory(chunk_key, &inventory)?; + } + Ok(()) + } +} + impl RawWorldTrait for RustyDBInterface { type Err = DBError; type UserState = UserState; @@ -200,7 +253,7 @@ impl RawWorldTrait for RustyDBInterface { fn new( path: Box, create_if_missing: bool, - _: &mut Self::UserState, + user_state: &mut UserState, ) -> Result { let mut opts = mcpe_options(COMPRESSION_LEVEL); opts.create_if_missing = create_if_missing; @@ -208,6 +261,7 @@ impl RawWorldTrait for RustyDBInterface { Ok(Self { db, phantom_data: PhantomData, + user_state, }) }