mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
* replace slot with ItemStackSeralizer * Dismantle current inv logic * Disassemble even more, items need fixing markd with TODO: Inv * Player inventory methods implmented * make some fields private * remove invalid comment * Partial screen handler and slot * Add armorslot * prepare for crafting * implement some more crafting traits * Fix ItemStack * Fix pickup and remove faulty crafting (getting reworked in inv revamp) * fix * fix error * add readme * move readme file * asd * remove readme * add uppsercase readme * Some more work * merge * Move from generics to dynamics * fix * move to same impl * Some changes * add player open logic * Basic impl of sync and listeners * Why did mojang complicate it so much * bruh * Simplify things with DefaultScreenHandlerBehaviour * Implement partial slot clicks * add * itemhashes are broken * Start implementing packets * fix deadlock * new vanilla update * Use static item refs and use Arc Mutex on invs * working normal click * fix deadlock * implement sync handler * small patch * Implement quick_move * Implement Swap click type * pickup, update bug * start fixing updates * fix pickup desync * Make Inventories non mutexes * Implement some finishing stuff * close screen on player leave * fix pick item * Move to item hashes * remove some logs * begin implementing barrels * Begin implementing barrel * implement barrels * fix clippy + typos * Fix merge conflicts * Fix lint error * don't use unwrap when getting equipment slot * Fix typo and single threaded * Accidentally removed tokio completley * Fix crash when opening barrel holding item * Add support for marking block entities dirty * Player Equipment changes * Make ScreenHandlerFactory own inventory instead of passing in optional * remove log * replace todo's * fix clippy --------- Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
250 lines
8.1 KiB
Rust
250 lines
8.1 KiB
Rust
use std::borrow::Cow;
|
|
|
|
use crate::VarInt;
|
|
use pumpkin_data::item::Item;
|
|
use pumpkin_world::item::ItemStack;
|
|
use serde::{
|
|
Deserialize, Serialize, Serializer,
|
|
de::{self, SeqAccess},
|
|
};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ItemStackSerializer<'a>(pub Cow<'a, ItemStack>);
|
|
|
|
impl<'de> Deserialize<'de> for ItemStackSerializer<'static> {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: de::Deserializer<'de>,
|
|
{
|
|
struct Visitor;
|
|
impl<'de> de::Visitor<'de> for Visitor {
|
|
type Value = ItemStackSerializer<'static>;
|
|
|
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
formatter.write_str("a valid Slot encoded in a byte sequence")
|
|
}
|
|
|
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
|
where
|
|
A: SeqAccess<'de>,
|
|
{
|
|
let item_count = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("Failed to decode VarInt"))?;
|
|
|
|
let slot = if item_count.0 == 0 {
|
|
ItemStackSerializer(Cow::Borrowed(&ItemStack::EMPTY))
|
|
} else {
|
|
let item_id = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No item id VarInt!"))?;
|
|
|
|
let num_components_to_add = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No component add length VarInt!"))?;
|
|
let num_components_to_remove = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No component remove length VarInt!"))?;
|
|
|
|
if num_components_to_add.0 != 0 || num_components_to_remove.0 != 0 {
|
|
return Err(de::Error::custom(
|
|
"Slot components are currently unsupported",
|
|
));
|
|
}
|
|
|
|
let item_id: u16 = item_id
|
|
.0
|
|
.try_into()
|
|
.map_err(|_| de::Error::custom("Invalid item id!"))?;
|
|
|
|
ItemStackSerializer(Cow::Owned(ItemStack::new(
|
|
item_count.0 as u8,
|
|
Item::from_id(item_id).unwrap_or(&Item::AIR),
|
|
)))
|
|
};
|
|
|
|
Ok(slot)
|
|
}
|
|
}
|
|
|
|
deserializer.deserialize_seq(Visitor)
|
|
}
|
|
}
|
|
|
|
impl Serialize for ItemStackSerializer<'_> {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
if self.0.is_empty() {
|
|
VarInt(0).serialize(serializer)
|
|
} else {
|
|
// TODO: Components
|
|
|
|
#[derive(Serialize)]
|
|
struct NetworkRepr {
|
|
item_count: VarInt,
|
|
item_id: VarInt,
|
|
components_to_add: VarInt,
|
|
components_to_remove: VarInt,
|
|
}
|
|
|
|
NetworkRepr {
|
|
item_count: self.0.item_count.into(),
|
|
item_id: self.0.item.id.into(),
|
|
components_to_add: 0.into(),
|
|
components_to_remove: 0.into(),
|
|
}
|
|
.serialize(serializer)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ItemStackSerializer<'_> {
|
|
pub fn to_stack(self) -> ItemStack {
|
|
self.0.into_owned()
|
|
}
|
|
}
|
|
|
|
impl From<ItemStack> for ItemStackSerializer<'_> {
|
|
fn from(item: ItemStack) -> Self {
|
|
ItemStackSerializer(Cow::Owned(item))
|
|
}
|
|
}
|
|
|
|
impl From<Option<ItemStack>> for ItemStackSerializer<'_> {
|
|
fn from(item: Option<ItemStack>) -> Self {
|
|
match item {
|
|
Some(item) => ItemStackSerializer::from(item),
|
|
None => ItemStackSerializer(Cow::Borrowed(&ItemStack::EMPTY)),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ItemComponentHash {
|
|
pub added: Vec<(VarInt, VarInt)>,
|
|
pub removed: Vec<VarInt>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ItemStackHash {
|
|
item_id: VarInt,
|
|
count: VarInt,
|
|
#[allow(dead_code)]
|
|
components: ItemComponentHash,
|
|
}
|
|
|
|
impl OptionalItemStackHash {
|
|
pub fn hash_equals(&self, other: &ItemStack) -> bool {
|
|
if let Some(hash) = &self.0 {
|
|
// TODO: Components
|
|
hash.item_id == other.item.id.into() && hash.count == other.item_count.into()
|
|
} else {
|
|
other.is_empty()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct OptionalItemStackHash(pub Option<ItemStackHash>);
|
|
|
|
impl<'de> Deserialize<'de> for OptionalItemStackHash {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: de::Deserializer<'de>,
|
|
{
|
|
struct Visitor;
|
|
impl<'de> de::Visitor<'de> for Visitor {
|
|
type Value = OptionalItemStackHash;
|
|
|
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
formatter.write_str("a valid Slot encoded in a byte sequence")
|
|
}
|
|
|
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
|
where
|
|
A: SeqAccess<'de>,
|
|
{
|
|
let is_some = seq
|
|
.next_element::<bool>()?
|
|
.ok_or(de::Error::custom("No is some bool!"))?;
|
|
if is_some {
|
|
let item_id = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No item id VarInt!"))?;
|
|
let count = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No item count VarInt!"))?;
|
|
|
|
let hashed_components = seq
|
|
.next_element::<ItemComponentHash>()?
|
|
.ok_or(de::Error::custom("No item component hash!"))?;
|
|
|
|
let item_stack_hash = ItemStackHash {
|
|
item_id,
|
|
count,
|
|
components: hashed_components,
|
|
};
|
|
Ok(OptionalItemStackHash(Some(item_stack_hash)))
|
|
} else {
|
|
Ok(OptionalItemStackHash(None))
|
|
}
|
|
}
|
|
}
|
|
|
|
deserializer.deserialize_seq(Visitor)
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for ItemComponentHash {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: de::Deserializer<'de>,
|
|
{
|
|
struct Visitor;
|
|
impl<'de> de::Visitor<'de> for Visitor {
|
|
type Value = ItemComponentHash;
|
|
|
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
formatter.write_str("a valid Slot encoded in a byte sequence")
|
|
}
|
|
|
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
|
where
|
|
A: SeqAccess<'de>,
|
|
{
|
|
let mut added = Vec::new();
|
|
let mut removed = Vec::new();
|
|
|
|
let added_length = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No added length VarInt!"))?;
|
|
for _ in 0..added_length.0 {
|
|
let component_id = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No component id VarInt!"))?;
|
|
let component_value = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No component value VarInt!"))?;
|
|
added.push((component_id, component_value));
|
|
}
|
|
|
|
let removed_length = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No removed length VarInt!"))?;
|
|
for _ in 0..removed_length.0 {
|
|
let component_id = seq
|
|
.next_element::<VarInt>()?
|
|
.ok_or(de::Error::custom("No component id VarInt!"))?;
|
|
removed.push(component_id);
|
|
}
|
|
|
|
Ok(ItemComponentHash { added, removed })
|
|
}
|
|
}
|
|
|
|
deserializer.deserialize_seq(Visitor)
|
|
}
|
|
}
|