Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue #112]Implementing missing level feature: Inventory #114

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/level/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
12 changes: 12 additions & 0 deletions crates/level/src/level/db_interface/inventory.rs
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct InventoryData {
pub items: Vec<InventoryItem>,
}

#[derive(Serialize, Deserialize)]
pub struct InventoryItem {
pub id: u32,
pub quantity: u32,
}
3 changes: 0 additions & 3 deletions crates/level/src/level/db_interface/key_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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,
}
Expand Down
1 change: 1 addition & 0 deletions crates/level/src/level/db_interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod bedrock_key;
pub mod db;
pub mod key_level;
pub mod rusty;
pub mod inventory;
56 changes: 55 additions & 1 deletion crates/level/src/level/db_interface/rusty.rs
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -74,6 +76,7 @@ const COMPRESSION_LEVEL: u8 = CompressionLevel::DefaultLevel as u8;
pub struct RustyDBInterface<UserState> {
db: DB,
phantom_data: PhantomData<UserState>,
user_state: UserState,
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Debug, Error)]
Expand Down Expand Up @@ -113,6 +116,56 @@ impl<UserState> RustyDBInterface<UserState> {
}
}

impl<UserState> RustyDBInterface<UserState> {
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;
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
self.set_subchunk_raw(*chunk_key, &serialized_inventory, &mut self.user_state)
}

pub fn load_inventory(&mut self, chunk_key: &ChunkKey) -> Result<Option<InventoryData>, DBError> {
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
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(
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
&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(
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
&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<UserState> RawWorldTrait for RustyDBInterface<UserState> {
type Err = DBError;
type UserState = UserState;
Expand Down Expand Up @@ -200,14 +253,15 @@ impl<UserState> RawWorldTrait for RustyDBInterface<UserState> {
fn new(
path: Box<Path>,
create_if_missing: bool,
_: &mut Self::UserState,
user_state: &mut UserState,
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<Self, Self::Err> {
let mut opts = mcpe_options(COMPRESSION_LEVEL);
opts.create_if_missing = create_if_missing;
let db = DB::open(path, opts)?;
Ok(Self {
db,
phantom_data: PhantomData,
user_state,
nakul-py marked this conversation as resolved.
Show resolved Hide resolved
})
}

Expand Down