prokits-network / inv-menu
一个用于创建和管理虚拟库存的 PocketMine-MP 病毒!
This package is not auto-updated.
Last update: 2024-09-22 12:01:41 UTC
README
InvMenu 是一个 PocketMine-MP 病毒,简化了创建和管理虚假库存的过程!
用法
InvMenu 支持将任何类型的 Inventory 创建为 GUI。
注意:您必须在启用插件之前注册 InvMenuHandler,然后才能开始创建 InvMenu 实例。
if(!InvMenuHandler::isRegistered()){ InvMenuHandler::register($this); }
创建 InvMenu 实例
InvMenu::create($identifier) 创建一个新的 InvMenu 实例。$identifier 必须是已注册的 InvMenuType 对象的标识符。InvMenu 包含 3 个预注册的 InvMenuType 标识符:InvMenu::TYPE_CHEST、InvMenu::TYPE_DOUBLE_CHEST 和 InvMenu::TYPE_HOPPER。
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
要访问此菜单的库存,您可以使用
$inventory = $menu->getInventory();
$inventory 实现了 pocketmine 的 Inventory 接口,因此您可以使用所有这些花哨的 pocketmine 库存方法。
$menu->getInventory()->setContents([ VanillaItems::DIAMOND_SWORD(), VanillaItems::DIAMOND_PICKAXE() ]); $menu->getInventory()->addItem(VanillaItems::DIAMOND_AXE()); $menu->getInventory()->setItem(3, VanillaItems::GOLD_INGOT());
要向玩家发送菜单,请使用
/** @var Player $player */ $menu->send($player);
是的,就是这样。很简单。
为菜单指定自定义名称
要设置菜单的自定义名称,请使用
$menu->setName("Custom Name");
您也可以在 InvMenu::send() 期间为每个玩家分别指定不同的菜单名称。
/** @var Player $player */ $menu->send($player, "Greetings, " . $player->getName());
验证菜单是否已发送给玩家
虽然不常见,但插件可能会阻止玩家打开库存。这也可能是一个尝试丢弃垃圾 InvMenu::send() 请求(如果您在没有延迟的情况下同时发送两个菜单,第一个菜单请求可能会被视为垃圾)。
/** @var string|null $name */ $menu->send($player, $name, function(bool $sent) : void{ if($sent){ // do something } });
处理菜单项交易
要处理发生在菜单库存中的交易,您可以指定一个 Closure 处理器,该处理器在 InvMenu 每次发生交易时被触发。您可以在该处理器中允许、取消并执行其他操作。要将交易处理器注册到菜单中,请使用
/** @var Closure $listener */ $menu->setListener($listener);
什么是 $listener?
/** * @param InvMenuTransaction $transaction * * Must return an InvMenuTransactionResult instance. * Return $transaction->continue() to continue the transaction. * Return $transaction->discard() to cancel the transaction. * @return InvMenuTransactionResult */ Closure(InvMenuTransaction $transaction) : InvMenuTransactionResult;
InvMenuTransaction 包含所有项目交易数据。
InvMenuTransaction::getPlayer() 返回触发交易的 Player。
InvMenuTransaction::getItemClicked() 返回玩家在菜单中点击的 Item。
InvMenuTransaction::getItemClickedWith() 返回玩家点击项目时手中的 Item。
InvMenuTransaction::getAction() 返回一个 SlotChangeAction 实例,以获取从菜单库存中点击的项目槽位索引。
InvMenuTransaction::getTransaction() 返回完整的 InventoryTransaction 实例。
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ $player = $transaction->getPlayer(); $itemClicked = $transaction->getItemClicked(); $itemClickedWith = $transaction->getItemClickedWith(); $action = $transaction->getAction(); $invTransaction = $transaction->getTransaction(); return $transaction->continue(); });
阻止玩家从菜单库存中取出苹果的处理程序
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ if($transaction->getItemClicked()->getId() === ItemIds::APPLE){ $player->sendMessage("You cannot take apples out of that inventory."); return $transaction->discard(); } return $transaction->continue(); });
防止玩家更改库存
您有两种方法可以防止玩家修改菜单的库存内容。
方法 #1:调用 InvMenuTransaction::discard()
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ // do something return $transaction->discard(); });
方法 #2:使用 InvMenu::readonly()
$menu->setListener(InvMenu::readonly());
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{ // do something }));
根据您的用例,您可能会发现其中一种方法比另一种更好。虽然 方法 #1 使您完全控制交易(例如,根据玩家是否有权限或玩家是否在特定区域等条件有条件地取消交易),但 方法 #2 减少了 InvMenuTransactionResult 导入和调用 InvMenutransaction::discard() 的冗余。
交易后执行任务
有些动作在玩家查看库存时不可能执行,例如发送表单——玩家在查看库存时无法查看表单。为此,您需要关闭菜单库存并确保他们已经关闭,可以通过等待他们的一侧的响应来实现。您可以通过向 InvMenuTransactionResult::then() 提供回调来实现此操作。
$menu->setListener(function(InvMenuTransaction $transaction) : InvMenuTransactionResult{ $transaction->getPlayer()->removeCurrentWindow(); return $transaction->discard()->then(function(Player $player) : void{ // $player === $transaction->getPlayer() // assert($player->isOnline()); $player->sendForm(new Form()); }); });
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{ $transaction->getPlayer()->removeCurrentWindow(); $transaction->then(function(Player $player) : void{ $player->sendForm(new Form()); }); }));
正在监听的玩家关闭或不再查看库存
要监听库存关闭触发器,请使用
/** @var Closure $listener */ $menu->setInventoryCloseListener($listener);
什么是 $listener?
/** * @param Player $player the player who closed the inventory. * * @param Inventory $inventory the inventory instance closed by the player. */ Closure(Player $player, Inventory $inventory) : void;
强制关闭或从玩家处移除菜单
/** @var Player $player */ $player->removeCurrentWindow();
注册自定义的InvMenu类型
假设您想向玩家发送一个投掷器库存。虽然InvMenu没有附带InvMenu::TYPE_DISPENSER,但您仍然可以通过注册一个包含有关投掷器库存外观信息的InvMenuType对象来创建一个投掷器InvMenu。
public const TYPE_DISPENSER = "myplugin:dispenser"; protected function onEnable() : void{ InvMenuHandler::getTypeRegistry()->register(self::TYPE_DISPENSER, InvMenuTypeBuilders::BLOCK_ACTOR_FIXED() ->setBlock(BlockFactory::getInstance()->get(BlockLegacyIds::DISPENSER, 0)) ->setBlockActorId("Dispenser") ->setSize(9) ->setNetworkWindowType(WindowTypes::DISPENSER) ->build()); }
太好了!现在您可以使用
$menu = InvMenu::create(self::TYPE_DISPENSER);
InvMenu 维基百科
使用InvMenu的应用、示例、教程和特色项目可以在InvMenu 维基百科上找到。