Beware matching items that aren't actually correct

This would only ever happen if we received the actions in the wrong order, but that wouldn't surprise me.
This commit is contained in:
Dylan K. Taylor 2017-09-13 11:37:10 +01:00
parent 5267c571e9
commit c1c290cd39
3 changed files with 15 additions and 9 deletions

View File

@ -106,6 +106,9 @@ abstract class BaseInventory implements Inventory{
return $this->slots[$index] !== null ? clone $this->slots[$index] : ItemFactory::get(Item::AIR, 0, 0);
}
/**
* @return Item[]
*/
public function getContents() : array{
return array_filter($this->slots->toArray(), function(Item $item = null){ return $item !== null; });
}
@ -196,13 +199,13 @@ abstract class BaseInventory implements Inventory{
}
}
public function first(Item $item) : int{
$count = max(1, $item->getCount());
$checkDamage = !$item->hasAnyDamageValue();
$checkTags = $item->hasCompoundTag();
public function first(Item $item, bool $exact = false) : int{
$count = $exact ? $item->getCount() : max(1, $item->getCount());
$checkDamage = $exact || !$item->hasAnyDamageValue();
$checkTags = $exact || $item->hasCompoundTag();
foreach($this->getContents() as $index => $i){
if($item->equals($i, $checkDamage, $checkTags) and $i->getCount() >= $count){
if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){
return $index;
}
}

View File

@ -149,14 +149,17 @@ interface Inventory{
public function all(Item $item) : array;
/**
* Will return the first slot has the same id and metadata (if not null) as the Item.
* -1 if not found, will check amount
* Returns the first slot number containing an item with the same ID, damage (if not any-damage), NBT (if not empty)
* and count >= to the count of the specified item stack.
*
* If $exact is true, only items with equal ID, damage, NBT and count will match.
*
* @param Item $item
* @param bool $exact
*
* @return int
*/
public function first(Item $item) : int;
public function first(Item $item, bool $exact = false) : int;
/**
* Returns the first empty slot, or -1 if not found

View File

@ -191,7 +191,7 @@ class NetworkInventoryAction{
$window = $player->getCraftingGrid();
//DROP_CONTENTS doesn't bother telling us what slot the item is in, so we find it ourselves
$inventorySlot = $window->first($this->oldItem);
$inventorySlot = $window->first($this->oldItem, true);
if($inventorySlot === -1){
throw new \InvalidStateException("Fake container " . get_class($window) . " for " . $player->getName() . " does not contain $this->oldItem");
}