muqsit/invmenu
Composer 安装命令:
composer require muqsit/invmenu
包简介
A PocketMine-MP virion to create and manage virtual inventories!
README 文档
README
Create and manage virtual inventories in PocketMine-MP.
Installation and setup
Download the compiled .phar file from Poggit CI and place it in your virions/ folder.
Read installation and using in a plugin
for a more elaborate guide on how to setup InvMenu library.
Note
You must register InvMenuHandler before you can use InvMenu.
// in class MyPlugin extends PluginBase: protected function onEnable() : void{ if(!InvMenuHandler::isRegistered()){ InvMenuHandler::register($this); } }
Create a virtual inventory
Quick start, use InvMenu::create(InvMenu::TYPE_CHEST)->send($player); to display a virtual chest inventory to a player.
InvMenu::create($identifier) creates an InvMenu instance. $identifier may be an identifier of a registered InvMenuType object.
InvMenu comes with 3 pre-registered inventory types of different sizes:
InvMenu::TYPE_CHEST- a 27-slot normal chest inventoryInvMenu::TYPE_DOUBLE_CHEST- a 54-slot double chest inventoryInvMenu::TYPE_HOPPER- a 5-slot hopper inventory
$menu = InvMenu::create(InvMenu::TYPE_CHEST); $inventory = $menu->getInventory();
As $inventory implements PocketMine's Inventory interface, you get to access all the fancy PocketMine inventory methods.
$menu->getInventory()->setContents([ VanillaItems::DIAMOND_SWORD(), VanillaItems::DIAMOND_PICKAXE() ]); $menu->getInventory()->addItem(VanillaItems::DIAMOND_AXE()); $menu->getInventory()->setItem(3, VanillaItems::GOLD_INGOT());
To send a menu to a player, use:
/** @var Player $player */ $menu->send($player);
Tip
One InvMenu can be sent to multiple players—even 2 players in different worlds, so everyone views and edits the same inventory as if it were one chest.
Set a custom name
There are two ways to name an InvMenu. You can either specify a global name (see method A), or you can set a name at the time you send the menu (see method B).
$menu->setName("Custom Name"); // method A $menu->send($player, "Greetings, " . $player->getName()); // method B
Verify whether a menu is sent successfully
InvMenu::send() is not guaranteed to succeed. A failure may arise from plugins cancelling InventoryOpenEvent, a disconnected player, or the player refusing the request (e.g., because they are in pause menu).
Use the $callback parameter to verify whether a menu has been opened.
$menu->send($player, callback: function(bool $success) : void{ if($success){ // player is viewing the menu } });
Monitor movement of items
InvMenu comes with a listener whereby developers can write logic to monitor movement of items in and out of inventory, and thereby take action. A listener is a callback with the following signature:
/** * @param InvMenuTransaction $transaction * * Return $transaction->continue() to continue the transaction. * Return $transaction->discard() to cancel the transaction. * @return InvMenuTransactionResult */ Closure(InvMenuTransaction $transaction) : InvMenuTransactionResult;
InvMenuTransaction::getPlayer()returns thePlayerthat triggered the transaction.InvMenuTransaction::getItemClicked()returns theItemthe player clicked in the menu. You may also useInvMenuTransaction::getOut().InvMenuTransaction::getItemClickedWith()returns theItemthe player had in their hand when clicking an item. You may also useInvMenuTransaction::getIn().InvMenuTransaction::getAction()returnsSlotChangeAction- you can get the slot that the player clicked in the menu.InvMenuTransaction::getTransaction()returns the completeInventoryTransactionholding all the above information.
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ $player = $transaction->getPlayer(); $itemClicked = $transaction->getItemClicked(); $itemClickedWith = $transaction->getItemClickedWith(); $action = $transaction->getAction(); $txn = $transaction->getTransaction(); return $transaction->continue(); });
The listener below does not allow players to take out apples from the menu:
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ if($transaction->getItemClicked()->getTypeId() === ItemTypeIds::APPLE){ $player->sendMessage("You cannot take apples out of that inventory."); return $transaction->discard(); } return $transaction->continue(); });
There are two methods you can use to prevent players from editing the menu. Either create a listener that discard()s
the transaction, or use InvMenu::readonly().
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ return $transaction->discard(); }); $menu->setListener(InvMenu::readonly()); // equivalent shorthand of the above // you can also pass a callback in InvMenu::readonly() $menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{ // do something }));
Alternatively, you may choose to write your own InventoryTransactionEvent listener that works on transactions on
$menu->getInventory(). However, an InvMenu listener is enough to fulfil most tasks.
Execute a task post-transaction
Few actions are not possible to invoke at the time a player is viewing an inventory, such as sending a form—a player
cannot view a form while viewing an inventory. Close the menu and utilize InvMenuTransactionResult::then() callback to
achieve this.
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ $transaction->getPlayer()->removeCurrentWindow(); return $transaction->discard()->then(function(Player $player) : void{ $player->sendForm(new Form()); }); }); // or if you are using InvMenu::readonly(): $menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{ $transaction->getPlayer()->removeCurrentWindow(); $transaction->then(function(Player $player) : void{ $player->sendForm(new Form()); }); }));
Monitor menu close events
Register an inventory close callback to run whenever a player closes the menu. An inventory close callback takes the following signature:
/** * @param Player $player the player that closed the menu * @param Inventory $inventory the inventory of the menu */ Closure(Player $player, Inventory $inventory) : void;
$menu->setInventoryCloseListener(function(Player $player, Inventory $inventory) : void{ $player->sendMessage("You are no longer viewing the menu."); });
Inventory close listener is fired during both—server-initiated requests (i.e., $player->removeCurrentWindow()) and
when the player closes the inventory on their end.
Advanced usage: Register a custom InvMenuType
Important
PocketMine does not register a dispenser block. As of PocketMine v5, the task of registering missing vanilla blocks is
excessively laborious and hence beyond the scope of this guide. pmmp/RegisterBlocksDemoPM5
has a nice guide on how to achieve this. Still overwhelmed? I wrote a drag-n-drop example plugin
that does all of it and registers a /dispenser command. With DevTools plugin installed, simply copy the code and
paste it in a new "DispenserInvMenuPlugin.php" file in your server's plugin folder.
InvMenu does not provide a 9-slot dispenser inventory. But you can still achieve this by registering a dispenser InvMenuType. You'll need to specify inventory size, block actor identifier (tile identifier), and the window type (network property) for the creation of the graphic (block) and inventory parts.
public const TYPE_DISPENSER = "myplugin:dispenser"; protected function onEnable() : void{ InvMenuHandler::getTypeRegistry()->register(self::TYPE_DISPENSER, InvMenuTypeBuilders::BLOCK_ACTOR_FIXED() ->setBlock(ExtraVanillaBlocks::DISPENSER()) ->setSize(9) ->setBlockActorId("Dispenser") ->setNetworkWindowType(WindowTypes::DISPENSER) ->build()); }
Sweet! Now you can create a dispenser menu using:
$menu = InvMenu::create(self::TYPE_DISPENSER);
InvMenu Wiki
Applications, examples, tutorials and featured projects using InvMenu can be found on the InvMenu Wiki.
muqsit/invmenu 适用场景与选型建议
muqsit/invmenu 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 5.35k 次下载、GitHub Stars 达 224, 最近一次更新时间为 2023 年 06 月 01 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 muqsit/invmenu 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 muqsit/invmenu 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 5.35k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 224
- 点击次数: 18
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: GPL-3.0
- 更新时间: 2023-06-01