add CSetContainerContent

This commit is contained in:
Edvin Bryntesson 2024-08-21 19:27:58 +02:00
parent 53f7b3b573
commit 9003ee3dcc
No known key found for this signature in database
3 changed files with 65 additions and 19 deletions

View File

@ -10,12 +10,12 @@ pub struct CSetContainerContent<'a> {
state_id: VarInt,
count: VarInt,
slot_data: &'a [Slot],
carried_item: Slot
carried_item: &'a Slot
}
impl<'a> CSetContainerContent<'a> {
pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: Slot) -> Self {
pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: &'a Slot) -> Self {
Self {
window_id,
state_id,

View File

@ -1,12 +1,9 @@
use crate::VarInt;
use pumpkin_world::item::Item;
use serde::{
de::{self, SeqAccess, Visitor},
Deserialize,
Serialize
};
use serde::{de::{self, SeqAccess, Visitor}, Deserialize, Serialize, Serializer};
use serde::ser::SerializeSeq;
#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Slot {
item_count: VarInt,
@ -76,6 +73,60 @@ impl<'de> Deserialize<'de> for Slot {
deserializer.deserialize_seq(VarIntVisitor)
}
}
impl Serialize for Slot {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if self.item_count == 0.into() {
let mut s = serializer.serialize_seq(Some(1))?;
s.serialize_element(&self.item_count)?;
s.end()
} else {
match (&self.num_components_to_add,&self.num_components_to_remove) {
(Some(to_add),Some(to_remove)) => {
let mut s = serializer.serialize_seq(Some(6))?;
s.serialize_element(&self.item_count)?;
s.serialize_element(self.item_id.as_ref().unwrap())?;
s.serialize_element(to_add)?;
s.serialize_element(to_remove)?;
s.serialize_element(self.components_to_add.as_ref().unwrap())?;
s.serialize_element(self.components_to_remove.as_ref().unwrap())?;
s.end()
}
(None, Some(to_remove)) => {
let mut s = serializer.serialize_seq(Some(5))?;
s.serialize_element(&self.item_count)?;
s.serialize_element(self.item_id.as_ref().unwrap())?;
s.serialize_element(&VarInt(0))?;
s.serialize_element(to_remove)?;
s.serialize_element(self.components_to_remove.as_ref().unwrap())?;
s.end()
}
(Some(to_add),None) => {
let mut s = serializer.serialize_seq(Some(5))?;
s.serialize_element(&self.item_count)?;
s.serialize_element(self.item_id.as_ref().unwrap())?;
s.serialize_element(to_add)?;
s.serialize_element(&VarInt(0))?;
s.serialize_element(self.components_to_add.as_ref().unwrap())?;
s.end()
}
(None,None) => {
let mut s = serializer.serialize_seq(Some(4))?;
s.serialize_element(&self.item_count)?;
s.serialize_element(&self.item_id.as_ref().unwrap())?;
s.serialize_element(&VarInt(0))?;
s.serialize_element(&VarInt(0))?;
s.end()
}
}
}
}
}
impl Slot {
pub fn to_item(self) -> Option<Item> {
let item_id = self.item_id?.0.try_into().unwrap();
@ -103,7 +154,7 @@ impl From<&Item> for Slot {
item_count: item.item_count.into(),
item_id: Some(item.item_id.into()),
// TODO: add these
num_components_to_add: None,
num_components_to_add:None,
num_components_to_remove: None,
components_to_add: None,
components_to_remove: None,

View File

@ -41,6 +41,7 @@ use pumpkin_text::TextComponent;
use std::io::Read;
use thiserror::Error;
use pumpkin_inventory::WindowType;
use pumpkin_protocol::bytebuf::ByteBuffer;
use pumpkin_protocol::client::play::COpenScreen;
use pumpkin_protocol::slot::Slot;
use pumpkin_world::item::Item;
@ -179,23 +180,18 @@ impl Client {
self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap()));
}
pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>) {
pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>, items: Option<Vec<Option<&Item>>>, carried_item: Option<&Item>) {
let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY.get("minecraft:menu").unwrap().entries.get(minecraft_menu_id).expect("Should be a valid menu id").get("protocol_id").unwrap()).into();
let title = TextComponent::text(window_title.unwrap_or(window_type.default_title()));
self.send_packet(&COpenScreen::new((window_type.clone() as u8 +1).into(),menu_protocol_id, title));
let temp_item = Item {
item_id: 91, // Diamond block
item_count: 64
};
self.set_container_content(window_type, Some([Some(&temp_item);27].to_vec()), None);
self.set_container_content(window_type, items, carried_item);
}
pub fn set_container_content<'a>(&mut self, window_type: WindowType, items: Option<Vec<Option<&'a Item>>>, carried_item: Option<&'a Item>) {
let player = self.player.as_ref().unwrap();
let slots: Vec<Slot> = {if let Some(mut items) = items {
items.extend(player.inventory.slots()
);
items.extend(player.inventory.slots());
items
} else {
player.inventory.slots()
@ -215,8 +211,7 @@ impl Client {
Slot::empty()
}
};
self.send_packet(&CSetContainerContent::new(window_type as u8, 10.into(), &slots, carried_item))
self.send_packet(&CSetContainerContent::new(window_type as u8+1, 0.into(), &slots, &carried_item));
}
pub async fn process_packets(&mut self, server: &mut Server) {