-
Notifications
You must be signed in to change notification settings - Fork 75
InvMenu v4.0 Changelog and Migration Notes
SessionizedInvMenu
SharedInvMenu
InvMenu::copyProperties()
InvMenu::createSessionized()
InvMenu::getInventoryForPlayer()
-
InvMenu::getInventory()
(<-SharedInvMenu::getInventory()
)
-
InvMenu::create()
now returnsInvMenu
instead ofSharedInvMenu
(SharedInvMenu
has been removed) -
InvMenu::readonly()
is now astatic
method and accepts a listener as it's first parameter. The listener has a signaturefunction(DeterministicInvMenuTransaction $transaction) : void
-
InvMenu::setListener($listener)
's$listener
signature has been changed tofunction(InvMenuTransaction $transaction) : InvMenuTransactionResult
This method has been removed. SessionizedInvMenu
was simply an InvMenu
wrapper that held multiple InvMenu
instances, mapped to player UUIDs. IOW, it was basically the end result of what you'd get if you were to have a non-sessionized InvMenu
for each player.
// InvMenu v3.0
$menu = InvMenu::createSessionized(InvMenu::TYPE_CHEST);
$menu->setName($name);
$menu->setListener($listener);
$menu->send($player1);
$menu->send($player2);
// InvMenu v4.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setName($name);
$menu->setListener($listener);
$menu->send($player1);
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setName($name);
$menu->setListener($listener);
$menu->send($player2);
The method signature was far too long and possibly resulted in unnecessary imports that either you, your IDE or your static analyzer didn't like. InvMenu::setListener()
now accepts only one parameter that holds it all — InvMenuTransaction
.
The return type of the listener has been changed from bool
to InvMenuTransactionResult
.
// InvMenu v3.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(function(Player $player, Item $itemClicked, Item $itemClickedWith, SlotChangeAction $action, InventoryTransaction $invTransaction) : bool{
if($itemClicked->getId() === ItemIds::APPLE){
return true; // allow transaction to process
}
return false; // cancel transaction
});
// InvMenu v4.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{
$player = $transaction->getPlayer();
$itemClicked = $transaction->getItemClicked();
$itemClickedWith = $transaction->getItemClickedWith();
$action = $transaction->getAction();
$invTransaction = $transaction->getInventoryTransaction();
if($itemClicked->getId() === ItemIds::APPLE){
return $transaction->continue();
}
return $transaction->discard();
});
In InvMenu v3.0, menus had a boolean readonly property to forcefully cancel the transaction. InvMenu::readonly()
(then - non-static), produced same results as a non-readonly menu returning false in it's listener.
InvMenu::create(...)->setListener(function(...) : bool{ return false; });
The fact that readonly always cancelled the transaction meant it wasn't necessary to return any boolean value in the listener, i.e listener can be type-hinted with void
... and so it was.. causing a mix in return types. Listeners' return type was then changed to bool|void
based on the state of the menu's readonly property - readonly (return void
), non-readonly (return bool
).
InvMenu::readonly()
in v4.0 is now a static property that returns a closure that can be passed to InvMenu::setListener()
instance that always returns false.
/** 1. Setting readonly without listener */
// InvMenu v3.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->readonly();
// InvMenu v4.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(InvMenu::readonly());
/** 2. Setting readonly with listener */
// InvMenu v3.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->readonly();
$menu->setListener(function(Player $player, Item $itemClicked, Item $itemClickedWith, SlotChangeAction $action, InventoryTransaction $invTransaction) : void{
});
// InvMenu v4.0
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{
$player = $transaction->getPlayer();
$itemClicked = $transaction->getItemClicked();
$itemClickedWith = $transaction->getItemClickedWith();
$action = $transaction->getAction();
$invTransaction = $transaction->getInventoryTransaction();
}));
Allows you to specify a closure that gets triggered after escaping from the event call stack and the client's network stack. This is useful when you need to do something like sending a form to a player (it isn't possible to send a form before or right after closing their inventory).
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{
if($transaction->getItemClicked()->getId() === ItemIds::APPLE){
return $transaction->continue()->then(function(Player $player) : void{
$player->sendForm(new AppleForm());
});
}
return $transaction->discard()->then(function(Player $player) : void{
$player->sendForm(new FallbackForm());
}));
});
BEWARE: the then()
callback will not get triggered if the player quits while the server is waiting for a confirmation from their side. The fact that then()
was triggered implies $player->isConnected()
.
For readonly() listeners, you can directly trigger DeterministicInvMenuTransaction::then()
.
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{
if($transaction->getItemClicked()->getId() === ItemIds::APPLE){
$transaction->then(function(Player $player) : void{
$player->sendForm(new AppleForm());
});
return;
}
$transaction->then(function(Player $player) : void{
$player->sendForm(new FallbackForm());
});
}));
PHPStan is a static analysis tool for PHP. You can read more about it here: https://phpstan.org/blog/find-bugs-in-your-code-without-writing-tests Based on your level, phpstan will warn you about incorrect closure signatures.