Skip to content

Commit

Permalink
Merge pull request #54 from Bryntet/master
Browse files Browse the repository at this point in the history
Add CSetContainerSlot and refactor container logic to own file
  • Loading branch information
lukas0008 authored Aug 22, 2024
2 parents f920f31 + 10bf309 commit e41748b
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 75 deletions.
23 changes: 23 additions & 0 deletions pumpkin-protocol/src/client/play/c_set_container_slot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::slot::Slot;
use crate::VarInt;
use pumpkin_macros::packet;
use serde::Serialize;
#[derive(Serialize)]
#[packet(0x15)]
pub struct CSetContainerSlot<'a> {
window_id: i8,
state_id: VarInt,
slot: i16,
slot_data: &'a Slot,
}

impl<'a> CSetContainerSlot<'a> {
pub fn new(window_id: i8, state_id: i32, slot: usize, slot_data: &'a Slot) -> Self {
Self {
window_id,
state_id: state_id.into(),
slot: slot.try_into().unwrap(),
slot_data,
}
}
}
2 changes: 2 additions & 0 deletions pumpkin-protocol/src/client/play/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod c_player_info_update;
mod c_player_remove;
mod c_remove_entities;
mod c_set_container_content;
mod c_set_container_slot;
mod c_set_held_item;
mod c_set_title;
mod c_spawn_player;
Expand Down Expand Up @@ -60,6 +61,7 @@ pub use c_player_info_update::*;
pub use c_player_remove::*;
pub use c_remove_entities::*;
pub use c_set_container_content::*;
pub use c_set_container_slot::*;
pub use c_set_held_item::*;
pub use c_set_title::*;
pub use c_spawn_player::*;
Expand Down
6 changes: 6 additions & 0 deletions pumpkin-protocol/src/slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,9 @@ impl From<&Item> for Slot {
}
}
}

impl From<Option<&Item>> for Slot {
fn from(item: Option<&Item>) -> Self {
item.map(Slot::from).unwrap_or(Slot::empty())
}
}
85 changes: 85 additions & 0 deletions pumpkin/src/client/container.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use pumpkin_core::text::TextComponent;
use pumpkin_inventory::WindowType;
use pumpkin_protocol::client::play::{COpenScreen, CSetContainerContent, CSetContainerSlot};
use pumpkin_protocol::slot::Slot;
use pumpkin_world::item::Item;

impl super::Client {
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,
));
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
} else {
player.inventory.slots()
}
.into_iter()
.map(|item| {
if let Some(item) = item {
Slot::from(item)
} else {
Slot::empty()
}
})
.collect()
};

let carried_item = {
if let Some(item) = carried_item {
item.into()
} else {
Slot::empty()
}
};
let packet =
CSetContainerContent::new(window_type as u8 + 1, 0.into(), &slots, &carried_item);
self.send_packet(&packet);
}

pub fn set_container_slot(
&mut self,
window_type: WindowType,
slot: usize,
item: Option<&Item>,
) {
self.send_packet(&CSetContainerSlot::new(
window_type as i8,
0,
slot,
&item.into(),
))
}
}
77 changes: 2 additions & 75 deletions pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ use pumpkin_protocol::{
client::{
config::CConfigDisconnect,
login::CLoginDisconnect,
play::{
CGameEvent, CPlayDisconnect, CSetContainerContent, CSyncPlayerPostion,
CSystemChatMessge,
},
play::{CGameEvent, CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge},
},
packet_decoder::PacketDecoder,
packet_encoder::PacketEncoder,
Expand All @@ -41,15 +38,12 @@ use pumpkin_protocol::{
ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket,
};

use pumpkin_inventory::WindowType;
use pumpkin_protocol::client::play::COpenScreen;
use pumpkin_protocol::slot::Slot;
use pumpkin_world::item::Item;
use std::io::Read;
use thiserror::Error;

pub mod authentication;
mod client_packet;
mod container;
pub mod player_packet;

pub struct PlayerConfig {
Expand Down Expand Up @@ -182,73 +176,6 @@ 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>,
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,
));
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
} else {
player.inventory.slots()
}
.into_iter()
.map(|item| {
if let Some(item) = item {
Slot::from(item)
} else {
Slot::empty()
}
})
.collect()
};

let carried_item = {
if let Some(item) = carried_item {
item.into()
} else {
Slot::empty()
}
};
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) {
let mut i = 0;
while i < self.client_packets_queue.len() {
Expand Down

0 comments on commit e41748b

Please sign in to comment.