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

Add CSetContainerSlot and refactor container logic to own file #54

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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