mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-11 07:11:30 +11:00
Use Option<InventoryId>
for open_inventory
on client (#167)
- automatically handle CloseContainer packet so the client updates open_inventory - Use `Option<InventoryId>` for `open_inventory` on client Co-authored-by: Ryan Johnson <ryanj00a@gmail.com>
This commit is contained in:
parent
c4ed95a7d3
commit
4194acaa67
|
@ -14,13 +14,13 @@ use tokio::sync::OwnedSemaphorePermit;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use valence_protocol::packets::s2c::play::{
|
use valence_protocol::packets::s2c::play::{
|
||||||
AcknowledgeBlockChange, ClearTitles, CombatDeath, CustomSoundEffect, DisconnectPlay,
|
AcknowledgeBlockChange, ClearTitles, CloseContainerS2c, CombatDeath, CustomSoundEffect,
|
||||||
EntityAnimationS2c, EntityEvent, GameEvent, KeepAliveS2c, LoginPlayOwned, OpenScreen,
|
DisconnectPlay, EntityAnimationS2c, EntityEvent, GameEvent, KeepAliveS2c, LoginPlayOwned,
|
||||||
PluginMessageS2c, RemoveEntitiesEncode, ResourcePackS2c, RespawnOwned, SetActionBarText,
|
OpenScreen, PluginMessageS2c, RemoveEntitiesEncode, ResourcePackS2c, RespawnOwned,
|
||||||
SetCenterChunk, SetContainerContentEncode, SetContainerSlotEncode, SetDefaultSpawnPosition,
|
SetActionBarText, SetCenterChunk, SetContainerContentEncode, SetContainerSlotEncode,
|
||||||
SetEntityMetadata, SetEntityVelocity, SetExperience, SetHealth, SetRenderDistance,
|
SetDefaultSpawnPosition, SetEntityMetadata, SetEntityVelocity, SetExperience, SetHealth,
|
||||||
SetSubtitleText, SetTitleAnimationTimes, SetTitleText, SynchronizePlayerPosition,
|
SetRenderDistance, SetSubtitleText, SetTitleAnimationTimes, SetTitleText,
|
||||||
SystemChatMessage, UnloadChunk, UpdateAttributes, UpdateTime,
|
SynchronizePlayerPosition, SystemChatMessage, UnloadChunk, UpdateAttributes, UpdateTime,
|
||||||
};
|
};
|
||||||
use valence_protocol::types::{
|
use valence_protocol::types::{
|
||||||
AttributeProperty, DisplayedSkinParts, GameMode, GameStateChangeReason, SoundCategory,
|
AttributeProperty, DisplayedSkinParts, GameMode, GameStateChangeReason, SoundCategory,
|
||||||
|
@ -251,8 +251,8 @@ pub struct Client<C: Config> {
|
||||||
/// The item currently held by the client's cursor in the inventory.
|
/// The item currently held by the client's cursor in the inventory.
|
||||||
cursor_item: Option<ItemStack>,
|
cursor_item: Option<ItemStack>,
|
||||||
/// The currently open inventory. The client can close the screen, making
|
/// The currently open inventory. The client can close the screen, making
|
||||||
/// this [`InventoryId::NULL`].
|
/// this [`Option::None`].
|
||||||
open_inventory: InventoryId,
|
open_inventory: Option<InventoryId>,
|
||||||
/// The current window ID. Incremented when inventories are opened.
|
/// The current window ID. Incremented when inventories are opened.
|
||||||
window_id: u8,
|
window_id: u8,
|
||||||
bits: ClientBits,
|
bits: ClientBits,
|
||||||
|
@ -330,7 +330,7 @@ impl<C: Config> Client<C> {
|
||||||
modified_slots: 0,
|
modified_slots: 0,
|
||||||
inv_state_id: Wrapping(0),
|
inv_state_id: Wrapping(0),
|
||||||
cursor_item: None,
|
cursor_item: None,
|
||||||
open_inventory: InventoryId::NULL,
|
open_inventory: None,
|
||||||
window_id: 0,
|
window_id: 0,
|
||||||
bits: ClientBits::new()
|
bits: ClientBits::new()
|
||||||
.with_got_keepalive(true)
|
.with_got_keepalive(true)
|
||||||
|
@ -898,14 +898,23 @@ impl<C: Config> Client<C> {
|
||||||
mem::replace(&mut self.cursor_item, new)
|
mem::replace(&mut self.cursor_item, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_inventory(&self) -> InventoryId {
|
pub fn open_inventory(&self) -> Option<InventoryId> {
|
||||||
self.open_inventory
|
self.open_inventory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Marks the client's currently open inventory as the given inventory.
|
||||||
pub fn set_open_inventory(&mut self, id: InventoryId) {
|
pub fn set_open_inventory(&mut self, id: InventoryId) {
|
||||||
if self.open_inventory != id {
|
if self.open_inventory != Some(id) {
|
||||||
self.bits.set_open_inventory_modified(true);
|
self.bits.set_open_inventory_modified(true);
|
||||||
self.open_inventory = id;
|
self.open_inventory = Some(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks the client's currently open inventory as closed.
|
||||||
|
pub fn set_close_inventory(&mut self) {
|
||||||
|
if self.open_inventory.is_some() {
|
||||||
|
self.bits.set_open_inventory_modified(true);
|
||||||
|
self.open_inventory = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1440,11 +1449,12 @@ impl<C: Config> Client<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the window the client has opened.
|
// Update the window the client has opened.
|
||||||
|
if let Some(inv_id) = self.open_inventory {
|
||||||
|
if let Some(inv) = inventories.get(inv_id) {
|
||||||
if self.bits.open_inventory_modified() {
|
if self.bits.open_inventory_modified() {
|
||||||
// Open a new window.
|
// Open a new window.
|
||||||
self.bits.set_open_inventory_modified(false);
|
self.bits.set_open_inventory_modified(false);
|
||||||
|
|
||||||
if let Some(inv) = inventories.get(self.open_inventory) {
|
|
||||||
self.window_id = self.window_id % 100 + 1;
|
self.window_id = self.window_id % 100 + 1;
|
||||||
self.inv_state_id += 1;
|
self.inv_state_id += 1;
|
||||||
|
|
||||||
|
@ -1460,12 +1470,17 @@ impl<C: Config> Client<C> {
|
||||||
slots: inv.slot_slice(),
|
slots: inv.slot_slice(),
|
||||||
carried_item: &self.cursor_item,
|
carried_item: &self.cursor_item,
|
||||||
})?;
|
})?;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Update an already open window.
|
// Update an already open window.
|
||||||
if let Some(inv) = inventories.get(self.open_inventory) {
|
|
||||||
inv.send_update(send, self.window_id, &mut self.inv_state_id)?;
|
inv.send_update(send, self.window_id, &mut self.inv_state_id)?;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// the inventory no longer exists, so close the window
|
||||||
|
send.append_packet(&CloseContainerS2c {
|
||||||
|
window_id: self.window_id,
|
||||||
|
})?;
|
||||||
|
self.open_inventory = None; // avoids setting the modified flag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.old_world = self.world;
|
self.old_world = self.world;
|
||||||
|
|
|
@ -378,9 +378,14 @@ pub(super) fn next_event_fallible<C: Config>(
|
||||||
carried_item: p.carried_item,
|
carried_item: p.carried_item,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C2sPlayPacket::CloseContainerC2s(p) => ClientEvent::CloseContainer {
|
C2sPlayPacket::CloseContainerC2s(p) => {
|
||||||
|
if client.window_id == p.window_id as u8 {
|
||||||
|
client.set_close_inventory();
|
||||||
|
}
|
||||||
|
ClientEvent::CloseContainer {
|
||||||
window_id: p.window_id,
|
window_id: p.window_id,
|
||||||
},
|
}
|
||||||
|
}
|
||||||
C2sPlayPacket::PluginMessageC2s(p) => ClientEvent::PluginMessage {
|
C2sPlayPacket::PluginMessageC2s(p) => ClientEvent::PluginMessage {
|
||||||
channel: p.channel.into(),
|
channel: p.channel.into(),
|
||||||
data: p.data.0.into(),
|
data: p.data.0.into(),
|
||||||
|
|
|
@ -186,6 +186,13 @@ pub mod play {
|
||||||
pub reset: bool,
|
pub reset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Encode, Decode, Packet)]
|
||||||
|
#[packet_id = 0x10]
|
||||||
|
pub struct CloseContainerS2c {
|
||||||
|
/// Ignored by notchian clients.
|
||||||
|
pub window_id: u8,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encode, Decode, Packet)]
|
#[derive(Clone, Debug, Encode, Decode, Packet)]
|
||||||
#[packet_id = 0x11]
|
#[packet_id = 0x11]
|
||||||
pub struct SetContainerContent {
|
pub struct SetContainerContent {
|
||||||
|
@ -693,6 +700,7 @@ pub mod play {
|
||||||
BossBar,
|
BossBar,
|
||||||
SetDifficulty,
|
SetDifficulty,
|
||||||
ClearTitles,
|
ClearTitles,
|
||||||
|
CloseContainerS2c,
|
||||||
SetContainerContent,
|
SetContainerContent,
|
||||||
SetContainerProperty,
|
SetContainerProperty,
|
||||||
SetContainerSlot,
|
SetContainerSlot,
|
||||||
|
|
Loading…
Reference in a new issue