Skip to content

Commit

Permalink
Merge branch 'main' into command_api
Browse files Browse the repository at this point in the history
  • Loading branch information
JackCrumpLeys authored Sep 12, 2023
2 parents 1c46726 + c3d112d commit 255a74d
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 206 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ env:

jobs:
valence-fmt:
name: Formatting
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand All @@ -30,6 +31,7 @@ jobs:
run: cargo fmt --all -- --check

valence-docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand All @@ -48,6 +50,7 @@ jobs:
run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --all-features --document-private-items

typos:
name: Typos
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand All @@ -57,6 +60,7 @@ jobs:
uses: crate-ci/[email protected]

valence-clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand Down Expand Up @@ -88,9 +92,8 @@ jobs:
include:
- style: default
flags: ""

name: Tests (${{ matrix.platform }})
runs-on: ${{ matrix.platform }}

steps:
- name: Checkout Actions Repository
uses: actions/checkout@v3
Expand All @@ -114,7 +117,8 @@ jobs:
- name: Run valence_nbt tests without preserve_order feature
run: cargo test -p valence_nbt --all-targets

extractor-tests:
extractor-build:
name: Build Extractor
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand All @@ -131,6 +135,7 @@ jobs:
working-directory: extractor

check-depgraph:
name: Dependency Graph (assets/depgraph.svg)
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand Down Expand Up @@ -184,7 +189,7 @@ jobs:
name: bad-depgraph
path: bad-depgraph/
udeps:
name: Check for unused dependencies
name: Unused Dependencies
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
Expand Down
10 changes: 6 additions & 4 deletions crates/valence_anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ impl Region {
None => return Err(RegionError::InvalidCompressionScheme(compression)),
};

let (data, _) = Compound::from_binary(&mut nbt_slice)?;
let (data, _) = valence_nbt::from_binary(&mut nbt_slice)?;

if !nbt_slice.is_empty() {
return Err(RegionError::TrailingNbtData);
Expand Down Expand Up @@ -553,15 +553,17 @@ impl Region {
compress_buf.clear();
let mut compress_cursor = Cursor::new(compress_buf);
match options.compression {
Compression::Gzip => chunk.to_binary(
Compression::Gzip => valence_nbt::to_binary(
chunk,
GzEncoder::new(&mut compress_cursor, flate2::Compression::default()),
"",
)?,
Compression::Zlib => chunk.to_binary(
Compression::Zlib => valence_nbt::to_binary(
chunk,
ZlibEncoder::new(&mut compress_cursor, flate2::Compression::default()),
"",
)?,
Compression::None => chunk.to_binary(&mut compress_cursor, "")?,
Compression::None => valence_nbt::to_binary(chunk, &mut compress_cursor, "")?,
}
let compress_buf = compress_cursor.into_inner();

Expand Down
27 changes: 26 additions & 1 deletion crates/valence_inventory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub use valence_server::protocol::packets::play::player_action_c2s::PlayerAction
use valence_server::protocol::packets::play::{
ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c,
OpenScreenS2c, PlayerActionC2s, ScreenHandlerSlotUpdateS2c, UpdateSelectedSlotC2s,
UpdateSelectedSlotS2c,
};
use valence_server::protocol::{VarInt, WritePacket};
use valence_server::text::IntoText;
Expand All @@ -54,6 +55,7 @@ impl Plugin for InventoryPlugin {
PostUpdate,
(
update_client_on_close_inventory.before(update_open_inventories),
update_player_selected_slot,
update_open_inventories,
update_player_inventories,
)
Expand Down Expand Up @@ -405,6 +407,16 @@ impl HeldItem {
pub fn slot(&self) -> u16 {
self.held_item_slot
}

pub fn set_slot(&mut self, slot: u16) {
// temp
assert!(
(36..=44).contains(&slot),
"slot index of {slot} out of bounds"
);

self.held_item_slot = slot;
}
}

/// The item stack that the client thinks it's holding under the mouse
Expand Down Expand Up @@ -1216,18 +1228,31 @@ pub struct UpdateSelectedSlotEvent {
pub slot: u8,
}

/// Handles the `HeldItem` component being changed on a client entity, which
/// indicates that the server has changed the selected hotbar slot.
fn update_player_selected_slot(mut clients: Query<(&mut Client, &HeldItem), Changed<HeldItem>>) {
for (mut client, held_item) in &mut clients {
client.write_packet(&UpdateSelectedSlotS2c {
slot: (held_item.held_item_slot - PLAYER_INVENTORY_MAIN_SLOTS_COUNT) as u8,
});
}
}

/// Client to Server HeldItem Slot
fn handle_update_selected_slot(
mut packets: EventReader<PacketEvent>,
mut clients: Query<&mut HeldItem>,
mut events: EventWriter<UpdateSelectedSlotEvent>,
) {
for packet in packets.iter() {
if let Some(pkt) = packet.decode::<UpdateSelectedSlotC2s>() {
if let Ok(mut held) = clients.get_mut(packet.client) {
if let Ok(mut mut_held) = clients.get_mut(packet.client) {
let held = mut_held.bypass_change_detection();
if pkt.slot > 8 {
// The client is trying to interact with a slot that does not exist, ignore.
continue;
}

held.held_item_slot = convert_hotbar_slot_id(pkt.slot);

events.send(UpdateSelectedSlotEvent {
Expand Down
33 changes: 29 additions & 4 deletions crates/valence_nbt/src/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! # Examples
//!
//! ```
//! use valence_nbt::{compound, Compound, List};
//! use valence_nbt::{compound, to_binary, Compound, List};
//!
//! let c = compound! {
//! "byte" => 5_i8,
Expand All @@ -18,21 +18,21 @@
//!
//! let mut buf = vec![];
//!
//! c.to_binary(&mut buf, "").unwrap();
//! to_binary(&c, &mut buf, "").unwrap();
//! ```
//!
//! Decode NBT data from its binary form.
//!
//! ```
//! use valence_nbt::{compound, Compound};
//! use valence_nbt::{compound, from_binary, Compound};
//!
//! let some_bytes = [10, 0, 0, 3, 0, 3, 105, 110, 116, 0, 0, 222, 173, 0];
//!
//! let expected_value = compound! {
//! "int" => 0xdead
//! };
//!
//! let (nbt, root_name) = Compound::from_binary(&mut some_bytes.as_slice()).unwrap();
//! let (nbt, root_name) = from_binary(&mut some_bytes.as_slice()).unwrap();
//!
//! assert_eq!(nbt, expected_value);
//! assert_eq!(root_name, "");
Expand All @@ -45,4 +45,29 @@ mod modified_utf8;
#[cfg(test)]
mod tests;

pub use decode::from_binary;
pub use encode::{to_binary, written_size};
pub use error::*;

use crate::Tag;

impl Tag {
/// Returns the name of this tag for error reporting purposes.
const fn name(self) -> &'static str {
match self {
Tag::End => "end",
Tag::Byte => "byte",
Tag::Short => "short",
Tag::Int => "int",
Tag::Long => "long",
Tag::Float => "float",
Tag::Double => "double",
Tag::ByteArray => "byte array",
Tag::String => "string",
Tag::List => "list",
Tag::Compound => "compound",
Tag::IntArray => "int array",
Tag::LongArray => "long array",
}
}
}
70 changes: 33 additions & 37 deletions crates/valence_nbt/src/binary/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,28 @@ use super::{Error, Result};
use crate::tag::Tag;
use crate::{Compound, List, Value};

impl Compound {
/// Decodes uncompressed NBT binary data from the provided slice.
///
/// The string returned in the tuple is the name of the root compound
/// (typically the empty string).
pub fn from_binary(slice: &mut &[u8]) -> Result<(Self, String)> {
let mut state = DecodeState { slice, depth: 0 };

let root_tag = state.read_tag()?;

// For cases such as Block Entity Data in the chunk packet.
// https://wiki.vg/Protocol#Chunk_Data_and_Update_Light
if root_tag == Tag::End {
return Ok((Compound::new(), String::new()));
}

if root_tag != Tag::Compound {
return Err(Error::new_owned(format!(
"expected root tag for compound (got {root_tag})",
)));
}
/// Decodes uncompressed NBT binary data from the provided slice.
///
/// The string returned in the tuple is the name of the root compound
/// (typically the empty string).
pub fn from_binary(slice: &mut &[u8]) -> Result<(Compound, String)> {
let mut state = DecodeState { slice, depth: 0 };

let root_tag = state.read_tag()?;

if root_tag != Tag::Compound {
return Err(Error::new_owned(format!(
"expected root tag for compound (got {})",
root_tag.name(),
)));
}

let root_name = state.read_string()?;
let root = state.read_compound()?;
let root_name = state.read_string()?;
let root = state.read_compound()?;

debug_assert_eq!(state.depth, 0);
debug_assert_eq!(state.depth, 0);

Ok((root, root_name))
}
Ok((root, root_name))
}

/// Maximum recursion depth to prevent overflowing the call stack.
Expand Down Expand Up @@ -183,23 +176,23 @@ impl DecodeState<'_, '_> {
.read_list(Tag::Double, 8, |st| st.read_double())?
.into()),
Tag::ByteArray => Ok(self
.read_list(Tag::ByteArray, 4, |st| st.read_byte_array())?
.read_list(Tag::ByteArray, 0, |st| st.read_byte_array())?
.into()),
Tag::String => Ok(self
.read_list(Tag::String, 2, |st| st.read_string())?
.read_list(Tag::String, 0, |st| st.read_string())?
.into()),
Tag::List => self
.check_depth(|st| Ok(st.read_list(Tag::List, 5, |st| st.read_any_list())?.into())),
.check_depth(|st| Ok(st.read_list(Tag::List, 0, |st| st.read_any_list())?.into())),
Tag::Compound => self.check_depth(|st| {
Ok(st
.read_list(Tag::Compound, 1, |st| st.read_compound())?
.read_list(Tag::Compound, 0, |st| st.read_compound())?
.into())
}),
Tag::IntArray => Ok(self
.read_list(Tag::IntArray, 4, |st| st.read_int_array())?
.read_list(Tag::IntArray, 0, |st| st.read_int_array())?
.into()),
Tag::LongArray => Ok(self
.read_list(Tag::LongArray, 4, |st| st.read_long_array())?
.read_list(Tag::LongArray, 0, |st| st.read_long_array())?
.into()),
}
}
Expand All @@ -211,7 +204,7 @@ impl DecodeState<'_, '_> {
fn read_list<T, F>(
&mut self,
elem_type: Tag,
min_elem_size: usize,
elem_size: usize,
mut read_elem: F,
) -> Result<Vec<T>>
where
Expand All @@ -221,19 +214,22 @@ impl DecodeState<'_, '_> {

if len.is_negative() {
return Err(Error::new_owned(format!(
"negative {elem_type} list length of {len}",
"negative {} list length of {len}",
elem_type.name()
)));
}

// Ensure we don't reserve more than the maximum amount of memory required given
// the size of the remaining input.
if len as u64 * min_elem_size as u64 > self.slice.len() as u64 {
if len as u64 * elem_size as u64 > self.slice.len() as u64 {
return Err(Error::new_owned(format!(
"{elem_type} list of length {len} exceeds remainder of input"
"{} list of length {len} exceeds remainder of input",
elem_type.name()
)));
}

let mut list = Vec::with_capacity(len as usize);
let mut list = Vec::with_capacity(if elem_size == 0 { 0 } else { len as usize });

for _ in 0..len {
list.push(read_elem(self)?);
}
Expand Down
Loading

0 comments on commit 255a74d

Please sign in to comment.