diff --git a/src/Player.php b/src/Player.php index 17293ea80..0a5eae992 100644 --- a/src/Player.php +++ b/src/Player.php @@ -288,10 +288,10 @@ class Player{ if($w === $data["tile"]){ $this->dataPacket(MC_CONTAINER_SET_SLOT, array( "windowid" => $id, - "slot" => $data["slotdata"]["Slot"], - "block" => $data["slotdata"]["id"], - "stack" => $data["slotdata"]["Count"], - "meta" => $data["slotdata"]["Damage"], + "slot" => $data["slot"], + "block" => $data["slotdata"]->getID(), + "stack" => $data["slotdata"]->count, + "meta" => $data["slotdata"]->getMetadata(), )); } } @@ -881,51 +881,41 @@ class Player{ break; } $tile = $this->windows[$data["windowid"]]; + if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $data["slot"] < 0 or ($tile->class === TILE_CHEST and $data["slot"] >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $data["slot"] >= FURNACE_SLOTS)){ + break; + } $done = false; $item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]); - $s = array( - "Count" => $item->count, - "Slot" => $data["slot"], - "id" => $item->getID(), - "Damage" => $item->getMetadata(), - ); - - foreach($tile->data["Items"] as $i => $slot){ - if($slot["Slot"] === $data["slot"]){ - $done = true; - if($item->getID() !== AIR and $slot["id"] == $item->getID()){ - if($slot["Count"] < $item->count){ - $this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot["Count"]); - }elseif($slot["Count"] > $item->count){ - $this->addItem($item->getID(), $item->getMetadata(), $slot["Count"] - $item->count); - } - $tile->data["Items"][$i] = $s; - }else{ - $this->removeItem($item->getID(), $item->getMetadata(), $item->count); - $this->addItem($slot["id"], $slot["Damage"], $slot["Count"]); - if($item->getID() === AIR or $item->count <= 0){ - unset($tile->data["Items"][$i]); - } - } - break; - } - } - - if($done === false){ - if($item->getID() !== AIR and $item->count > 0){ - $this->removeItem($item->getID(), $item->getMetadata(), $item->count); - $tile->data["Items"][] = $s; - } - } - - $this->server->api->dhandle("tile.container.slot", array( + $slot = $tile->getSlot($data["slot"]); + $done = true; + if($this->server->api->dhandle("player.container.slot", array( "tile" => $tile, "slot" => $data["slot"], - "slotdata" => $s, + "slotdata" => $slot, + "itemdata" => $item, "player" => $this, - )); - $this->server->handle("tile.update", $tile); + )) === false){ + $this->dataPacket(MC_CONTAINER_SET_SLOT, array( + "windowid" => $data["windowid"], + "slot" => $data["slot"], + "block" => $slot->getID(), + "stack" => $slot->count, + "meta" => $slot->getMetadata(), + )); + break; + } + if($item->getID() !== AIR and $slot->getID() == $item->getID()){ + if($slot->count < $item->count){ + $this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count); + }elseif($slot->count > $item->count){ + $this->addItem($item->getID(), $item->getMetadata(), $slot->count - $item->count); + } + }else{ + $this->removeItem($item->getID(), $item->getMetadata(), $item->count); + $this->addItem($slot->getID(), $slot->getMetadata(), $slot->count); + } + $tile->setSlot($data["slot"], $item); break; case MC_SEND_INVENTORY: //TODO, Mojang, enable this ´^_^` break; diff --git a/src/material/block/solid/Chest.php b/src/material/block/solid/Chest.php index 8e58ed45f..9c98baf51 100644 --- a/src/material/block/solid/Chest.php +++ b/src/material/block/solid/Chest.php @@ -104,17 +104,17 @@ class ChestBlock extends SolidBlock{ "slots" => 27, "title" => "Chest", )); - foreach($chest->data["Items"] as $slot){ - if($slot["Slot"] < 0 or $slot["Slot"] >= 27){ - continue; + for($s = 0; $s < 3; ++$s){ + $slot = $chest->getSlot($s); + if($slot->getID() > 0 and $slot->count > 0){ + $player->dataPacket(MC_CONTAINER_SET_SLOT, array( + "windowid" => $id, + "slot" => $s, + "block" => $slot->getID(), + "stack" => $slot->count, + "meta" => $slot->getMetadata(), + )); } - $player->dataPacket(MC_CONTAINER_SET_SLOT, array( - "windowid" => $id, - "slot" => $slot["Slot"], - "block" => $slot["id"], - "stack" => $slot["Count"], - "meta" => $slot["Damage"], - )); } return true; diff --git a/src/world/TileEntity.php b/src/world/TileEntity.php index 50da034c1..f10bac358 100644 --- a/src/world/TileEntity.php +++ b/src/world/TileEntity.php @@ -28,6 +28,9 @@ the Free Software Foundation, either version 3 of the License, or define("TILE_SIGN", "Sign"); define("TILE_CHEST", "Chest"); + define("CHEST_SLOTS", 27); +define("TILE_FURNACE", "Furnace"); + define("FURNACE_SLOTS", 3); class TileEntity extends stdClass{ public $name; @@ -70,6 +73,55 @@ class TileEntity extends stdClass{ return false; } } + + public function getSlotIndex($s){ + if($this->class !== TILE_CHEST and $this->class !== TILE_FURNACE){ + return false; + } + foreach($this->data["Items"] as $i => $slot){ + if($slot["Slot"] === $s){ + return $i; + } + } + return -1; + } + + public function getSlot($s){ + $i = $this->getSlotIndex($s); + if($i === false or $i < 0){ + return BlockAPI::getItem(AIR, 0, 0); + }else{ + return BlockAPI::getItem($this->data["Items"][$i]["id"], $this->data["Items"][$i]["Damage"], $this->data["Items"][$i]["Count"]); + } + } + + public function setSlot($s, Item $item){ + $i = $this->getSlotIndex($s); + $d = array( + "Count" => $item->count, + "Slot" => $s, + "id" => $item->getID(), + "Damage" => $item->getMetadata(), + ); + if($i === false){ + return false; + }elseif($item->getID() === AIR or $item->count <= 0){ + if($i >= 0){ + unset($this->data["Items"][$i]); + } + }elseif($i < 0){ + $this->data["Items"][] = $d; + }else{ + $this->data["Items"][$i] = $d; + } + $this->server->api->dhandle("tile.container.slot", array( + "tile" => $this, + "slot" => $s, + "slotdata" => $item, + )); + $this->server->handle("tile.update", $this); + return true; + } public function spawn($player, $queue = false){ if($this->closed){