mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 09:19:42 +00:00
Update ContainerInventory on Transaction refused
This commit is contained in:
parent
f795a3f565
commit
f66560ccd4
@ -2011,6 +2011,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
break;
|
||||
}
|
||||
$this->craftingType = 0;
|
||||
$this->currentTransaction = null;
|
||||
if(isset($this->windowIndex[$packet->windowid])){
|
||||
$this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$packet->windowid], $this));
|
||||
$this->removeWindow($this->windowIndex[$packet->windowid]);
|
||||
@ -2046,13 +2047,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
|
||||
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.5)){
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.4)){
|
||||
if($this->currentTransaction instanceof SimpleTransactionGroup){
|
||||
foreach($this->currentTransaction->getInventories() as $inventory){
|
||||
$inventory->sendContents($inventory->getViewers());
|
||||
}
|
||||
}
|
||||
$this->currentTransaction = new SimpleTransactionGroup();
|
||||
$this->currentTransaction = new SimpleTransactionGroup($this);
|
||||
}
|
||||
|
||||
$this->currentTransaction->addTransaction($transaction);
|
||||
@ -2062,6 +2063,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->currentTransaction = null;
|
||||
break;
|
||||
}
|
||||
console("tx#".spl_object_hash($this->currentTransaction)." EXECUTED");
|
||||
foreach($this->currentTransaction->getTransactions() as $ts){
|
||||
$inv = $ts->getInventory();
|
||||
if($inv instanceof FurnaceInventory){
|
||||
|
@ -44,7 +44,7 @@ abstract class BaseInventory implements Inventory{
|
||||
protected $title;
|
||||
/** @var Item[] */
|
||||
protected $slots = [];
|
||||
/** @var \SplObjectStorage<Player> */
|
||||
/** @var Player[] */
|
||||
protected $viewers = [];
|
||||
/** @var InventoryHolder */
|
||||
protected $holder;
|
||||
@ -58,7 +58,6 @@ abstract class BaseInventory implements Inventory{
|
||||
*/
|
||||
public function __construct(InventoryHolder $holder, InventoryType $type, array $items = [], $overrideSize = null, $overrideTitle = null){
|
||||
$this->holder = $holder;
|
||||
$this->viewers = new \SplObjectStorage();
|
||||
|
||||
$this->type = $type;
|
||||
if($overrideSize !== null){
|
||||
@ -121,12 +120,12 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
}
|
||||
|
||||
public function setItem($index, Item $item){
|
||||
public function setItem($index, Item $item, $source = null){
|
||||
$item = clone $item;
|
||||
if($index < 0 or $index >= $this->size){
|
||||
return false;
|
||||
}elseif($item->getID() === 0){
|
||||
$this->clear($index);
|
||||
$this->clear($index, $source);
|
||||
}
|
||||
|
||||
$holder = $this->getHolder();
|
||||
@ -141,7 +140,7 @@ abstract class BaseInventory implements Inventory{
|
||||
|
||||
$old = $this->getItem($index);
|
||||
$this->slots[$index] = clone $item;
|
||||
$this->onSlotChange($index, $old);
|
||||
$this->onSlotChange($index, $old, $source);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -296,7 +295,7 @@ abstract class BaseInventory implements Inventory{
|
||||
return $slots;
|
||||
}
|
||||
|
||||
public function clear($index){
|
||||
public function clear($index, $source = null){
|
||||
if(isset($this->slots[$index])){
|
||||
$item = Item::get(Item::AIR, null, 0);
|
||||
$old = $this->slots[$index];
|
||||
@ -316,7 +315,7 @@ abstract class BaseInventory implements Inventory{
|
||||
unset($this->slots[$index]);
|
||||
}
|
||||
|
||||
$this->onSlotChange($index, $old);
|
||||
$this->onSlotChange($index, $old, $source);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -328,9 +327,12 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
}
|
||||
|
||||
public function getViewers(){
|
||||
public function getViewers($source = null){
|
||||
$viewers = [];
|
||||
foreach($this->viewers as $viewer){
|
||||
if($viewer === $source){
|
||||
continue;
|
||||
}
|
||||
$viewers[] = $viewer;
|
||||
}
|
||||
|
||||
@ -359,15 +361,15 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
public function onOpen(Player $who){
|
||||
$this->viewers->attach($who);
|
||||
$this->viewers[spl_object_hash($who)] = $who;
|
||||
}
|
||||
|
||||
public function onClose(Player $who){
|
||||
$this->viewers->detach($who);
|
||||
unset($this->viewers[spl_object_hash($who)]);
|
||||
}
|
||||
|
||||
public function onSlotChange($index, $before){
|
||||
$this->sendSlot($index, $this->getViewers());
|
||||
public function onSlotChange($index, $before, $source = null){
|
||||
$this->sendSlot($index, $this->getViewers($source));
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,6 +32,8 @@ class BaseTransaction implements Transaction{
|
||||
protected $sourceItem;
|
||||
/** @var Item */
|
||||
protected $targetItem;
|
||||
/** @var float */
|
||||
protected $creationTime;
|
||||
|
||||
/**
|
||||
* @param Inventory $inventory
|
||||
@ -44,6 +46,11 @@ class BaseTransaction implements Transaction{
|
||||
$this->slot = (int) $slot;
|
||||
$this->sourceItem = clone $sourceItem;
|
||||
$this->targetItem = clone $targetItem;
|
||||
$this->creationTime = microtime(true);
|
||||
}
|
||||
|
||||
public function getCreationTime(){
|
||||
return $this->creationTime;
|
||||
}
|
||||
|
||||
public function getInventory(){
|
||||
|
@ -53,8 +53,6 @@ class ChestInventory extends ContainerInventory{
|
||||
}
|
||||
|
||||
public function onClose(Player $who){
|
||||
parent::onClose($who);
|
||||
|
||||
if(count($this->getViewers()) === 1){
|
||||
$pk = new TileEventPacket;
|
||||
$pk->x = $this->getHolder()->getX();
|
||||
@ -64,5 +62,6 @@ class ChestInventory extends ContainerInventory{
|
||||
$pk->case2 = 0;
|
||||
Server::getInstance()->broadcastPacket($this->getHolder()->getLevel()->getPlayers(), $pk);
|
||||
}
|
||||
parent::onClose($who);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ use pocketmine\math\Vector3;
|
||||
|
||||
abstract class ContainerInventory extends BaseInventory{
|
||||
public function onOpen(Player $who){
|
||||
parent::onOpen($who);
|
||||
$pk = new ContainerOpenPacket;
|
||||
$pk->windowid = $who->getWindowId($this);
|
||||
$pk->type = $this->getType()->getNetworkType();
|
||||
@ -49,5 +50,6 @@ abstract class ContainerInventory extends BaseInventory{
|
||||
$pk = new ContainerClosePacket;
|
||||
$pk->windowid = $who->getWindowId($this);
|
||||
$who->dataPacket($pk);
|
||||
parent::onClose($who);
|
||||
}
|
||||
}
|
@ -34,10 +34,11 @@ class CraftingTransactionGroup extends SimpleTransactionGroup{
|
||||
/** @var Recipe */
|
||||
protected $recipe = null;
|
||||
|
||||
public function __construct(TransactionGroup $group){
|
||||
public function __construct(SimpleTransactionGroup $group){
|
||||
parent::__construct();
|
||||
$this->transactions = $group->getTransactions();
|
||||
$this->inventories = $group->getInventories();
|
||||
$this->source = $group->getSource();
|
||||
|
||||
$this->matchItems($this->output, $this->input);
|
||||
}
|
||||
@ -97,7 +98,7 @@ class CraftingTransactionGroup extends SimpleTransactionGroup{
|
||||
}
|
||||
|
||||
foreach($this->transactions as $transaction){
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem());
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem(), $this->getSource());
|
||||
}
|
||||
$this->hasExecuted = true;
|
||||
|
||||
|
@ -50,12 +50,12 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
|
||||
return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->right->getSize());
|
||||
}
|
||||
|
||||
public function setItem($index, Item $item){
|
||||
return $index < $this->left->getSize() ? $this->left->setItem($index, $item) : $this->right->setItem($index - $this->right->getSize(), $item);
|
||||
public function setItem($index, Item $item, $source = null){
|
||||
return $index < $this->left->getSize() ? $this->left->setItem($index, $item, $source) : $this->right->setItem($index - $this->right->getSize(), $item, $source);
|
||||
}
|
||||
|
||||
public function clear($index){
|
||||
return $index < $this->left->getSize() ? $this->left->clear($index) : $this->right->clear($index - $this->right->getSize());
|
||||
public function clear($index, $source = null){
|
||||
return $index < $this->left->getSize() ? $this->left->clear($index, $source) : $this->right->clear($index - $this->right->getSize(), $source);
|
||||
}
|
||||
|
||||
public function getContents(){
|
||||
|
@ -53,13 +53,15 @@ interface Inventory{
|
||||
/**
|
||||
* Puts an Item in a slot.
|
||||
* If a plugin refuses the update or $index is invalid, it'll return false
|
||||
* If a source Player is specified, it won't send a Inventory update to it
|
||||
*
|
||||
* @param int $index
|
||||
* @param Item $item
|
||||
* @param int $index
|
||||
* @param Item $item
|
||||
* @param Player $source
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setItem($index, Item $item);
|
||||
public function setItem($index, Item $item, $source = null);
|
||||
|
||||
/**
|
||||
* Stores the given Items in the inventory. This will try to fill
|
||||
@ -160,11 +162,12 @@ interface Inventory{
|
||||
/**
|
||||
* Will clear a specific slot
|
||||
*
|
||||
* @param int $index
|
||||
* @param int $index
|
||||
* @param Player $source
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear($index);
|
||||
public function clear($index, $source = null);
|
||||
|
||||
/**
|
||||
* Clears all the slots
|
||||
@ -175,9 +178,11 @@ interface Inventory{
|
||||
* Gets all the Players viewing the inventory
|
||||
* Players will be viewing their inventory at all times, even when not open.
|
||||
*
|
||||
* @param Player $source
|
||||
*
|
||||
* @return Player[]
|
||||
*/
|
||||
public function getViewers();
|
||||
public function getViewers($source = null);
|
||||
|
||||
/**
|
||||
* @return InventoryType
|
||||
@ -211,8 +216,9 @@ interface Inventory{
|
||||
public function onClose(Player $who);
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param Item|null $before
|
||||
* @param int $index
|
||||
* @param Item $before
|
||||
* @param Player $source
|
||||
*/
|
||||
public function onSlotChange($index, $before);
|
||||
public function onSlotChange($index, $before, $source = null);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ class PlayerInventory extends BaseInventory{
|
||||
}
|
||||
}
|
||||
|
||||
public function onSlotChange($index, $before){
|
||||
public function onSlotChange($index, $before, $source = null){
|
||||
parent::onSlotChange($index, $before);
|
||||
|
||||
if($index >= $this->getSize()){
|
||||
@ -196,7 +196,7 @@ class PlayerInventory extends BaseInventory{
|
||||
return $this->setItem($this->getSize(), $boots);
|
||||
}
|
||||
|
||||
public function setItem($index, Item $item){
|
||||
public function setItem($index, Item $item, $source = null){
|
||||
if($index < 0 or $index >= $this->size){
|
||||
return false;
|
||||
}
|
||||
@ -211,15 +211,18 @@ class PlayerInventory extends BaseInventory{
|
||||
}
|
||||
$item = $ev->getNewItem();
|
||||
}
|
||||
|
||||
$old = $this->getItem($index);
|
||||
$this->slots[$index] = clone $item;
|
||||
$this->onSlotChange($index, $old);
|
||||
if($item->getID() === 0){
|
||||
$this->clear($index, $source);
|
||||
}else{
|
||||
$old = $this->getItem($index);
|
||||
$this->slots[$index] = clone $item;
|
||||
$this->onSlotChange($index, $old, $source);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function clear($index){
|
||||
public function clear($index, $source = null){
|
||||
if(isset($this->slots[$index])){
|
||||
$item = Item::get(Item::AIR, null, 0);
|
||||
$old = $this->slots[$index];
|
||||
@ -239,7 +242,7 @@ class PlayerInventory extends BaseInventory{
|
||||
unset($this->slots[$index]);
|
||||
}
|
||||
|
||||
$this->onSlotChange($index, $old);
|
||||
$this->onSlotChange($index, $old, $source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\event\inventory\InventoryTransactionEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
/**
|
||||
@ -31,6 +32,8 @@ use pocketmine\Server;
|
||||
class SimpleTransactionGroup implements TransactionGroup{
|
||||
private $creationTime;
|
||||
protected $hasExecuted = false;
|
||||
/** @var Player */
|
||||
protected $source = null;
|
||||
|
||||
/** @var Inventory[] */
|
||||
protected $inventories = [];
|
||||
@ -38,8 +41,19 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
/** @var Transaction[] */
|
||||
protected $transactions = [];
|
||||
|
||||
public function __construct(){
|
||||
/**
|
||||
* @param Player $source
|
||||
*/
|
||||
public function __construct(Player $source = null){
|
||||
$this->creationTime = microtime(true);
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Player
|
||||
*/
|
||||
public function getSource(){
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
public function getCreationTime(){
|
||||
@ -55,6 +69,18 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
}
|
||||
|
||||
public function addTransaction(Transaction $transaction){
|
||||
if(isset($this->transactions[spl_object_hash($transaction)])){
|
||||
return;
|
||||
}
|
||||
foreach($this->transactions as $hash => $tx){
|
||||
if($tx->getInventory() === $transaction->getInventory() and $tx->getSlot() === $transaction->getSlot()){
|
||||
if($transaction->getCreationTime() >= $tx->getCreationTime()){
|
||||
unset($this->transactions[$hash]);
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->transactions[spl_object_hash($transaction)] = $transaction;
|
||||
$this->inventories[spl_object_hash($transaction->getInventory())] = $transaction->getInventory();
|
||||
}
|
||||
@ -100,9 +126,6 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
$haveItems = [];
|
||||
$needItems = [];
|
||||
$this->matchItems($haveItems, $needItems);
|
||||
$input = "";
|
||||
$output = "";
|
||||
|
||||
return count($haveItems) === 0 and count($needItems) === 0 and count($this->transactions) > 0;
|
||||
}
|
||||
|
||||
@ -120,7 +143,7 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
}
|
||||
|
||||
foreach($this->transactions as $transaction){
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem());
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem(), $this->getSource());
|
||||
}
|
||||
|
||||
$this->hasExecuted = true;
|
||||
|
@ -44,4 +44,9 @@ interface Transaction{
|
||||
* @return Item
|
||||
*/
|
||||
public function getTargetItem();
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getCreationTime();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user