clamp ItemStack item count to range 1-127 (#110)

This commit is contained in:
Carson McManus 2022-10-11 14:10:04 -04:00 committed by GitHub
parent 23fdc41610
commit a02b657f3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 13 deletions

View file

@ -8,13 +8,6 @@ use crate::protocol::{Decode, Encode, VarInt};
include!(concat!(env!("OUT_DIR"), "/item.rs"));
#[derive(Debug, Clone, PartialEq)]
pub struct ItemStack {
pub item: ItemKind,
pub item_count: u8,
pub nbt: Option<Compound>,
}
impl Encode for ItemKind {
fn encode(&self, w: &mut impl std::io::Write) -> anyhow::Result<()> {
VarInt(self.to_raw() as i32).encode(w)
@ -30,6 +23,37 @@ impl Decode for ItemKind {
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ItemStack {
pub item: ItemKind,
item_count: u8,
pub nbt: Option<Compound>,
}
impl ItemStack {
const STACK_MIN: u8 = 1;
const STACK_MAX: u8 = 127;
pub fn new(item: ItemKind, count: u8, nbt: Option<Compound>) -> Self {
Self {
item,
item_count: count.clamp(Self::STACK_MIN, Self::STACK_MAX),
nbt,
}
}
/// Gets the number of items in this stack.
pub fn count(&self) -> u8 {
self.item_count
}
/// Sets the number of items in this stack. Values are clamped to 1-127,
/// which are the positive values accepted by clients.
pub fn set_count(&mut self, count: u8) {
self.item_count = count.clamp(Self::STACK_MIN, Self::STACK_MAX)
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -52,4 +76,12 @@ mod tests {
assert_eq!(BlockKind::NetherPortal.to_item_kind(), ItemKind::Air);
}
#[test]
fn item_stack_clamps_count() {
let mut stack = ItemStack::new(ItemKind::Stone, 200, None);
assert_eq!(stack.item_count, ItemStack::STACK_MAX);
stack.set_count(201);
assert_eq!(stack.item_count, ItemStack::STACK_MAX);
}
}

View file

@ -18,7 +18,7 @@ impl Encode for Slot {
Some(s) => {
true.encode(w)?;
s.item.encode(w)?;
s.item_count.encode(w)?;
s.count().encode(w)?;
match &s.nbt {
Some(n) => n.encode(w),
None => 0u8.encode(w),
@ -34,15 +34,15 @@ impl Decode for Slot {
if !present {
return Ok(None);
}
Ok(Some(ItemStack {
item: ItemKind::decode(r)?,
item_count: u8::decode(r)?,
nbt: if r.first() == Some(&0) {
Ok(Some(ItemStack::new(
ItemKind::decode(r)?,
u8::decode(r)?,
if r.first() == Some(&0) {
r.read_u8()?;
None
} else {
Some(Compound::decode(r)?)
},
}))
)))
}
}