diff --git a/.poggit.yml b/.poggit.yml index 2345e61..f5dce21 100644 --- a/.poggit.yml +++ b/.poggit.yml @@ -7,10 +7,10 @@ projects: icon: icon.png libs: - src: poggit/libasynql/libasynql - version: ^3.2.0 + version: ^3.3.0 - src: muqsit/InvMenu/InvMenu branch: master - version: 2.1.0 + version: 3.1.0 - src: SOF3/await-generator/await-generator version: ^2.2.0 - src: JackMD/UpdateNotifier/UpdateNotifier diff --git a/README.md b/README.md index 5cc1c7a..6f72bb0 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,72 @@ # AuctionHouse [![](https://poggit.pmmp.io/shield.state/AuctionHouse)](https://poggit.pmmp.io/p/AuctionHouse) [![](https://poggit.pmmp.io/shield.dl.total/AuctionHouse)](https://poggit.pmmp.io/p/AuctionHouse) - -Feature-packed AuctionHouse plugin for PocketMine-MP - -## Overview -AuctionHouse allows players to list their items for sale and purchase items that others have listed for sale. - -![AuctionHouse](https://github.com/Shock95x/AuctionHouse/blob/master/img/auctionhouse.png) ---- -## Features ->- Chest GUI ->- Config (See below) ->- Multi-lang support ->- Custom Events ->- Economy plugin support (EconomyAPI as of now) ->- SQLite database support (MySQL coming soon) ->- Customizable messages -- And more coming soon! ---- -## Download -Check the [releases tab](https://github.com/Shock95x/AuctionHouse/releases) or [PoggitCI](https://poggit.pmmp.io/ci/Shock95x/AuctionHouse/AuctionHouse/) - ---- -## Config -```yaml ---- -# DO NOT EDIT THIS VALUE, INTERNAL USE ONLY. -config-version: 1 -# Sets the prefix for this plugin. -prefix: "[&l&6Auction House&r]" -# Sets the default language for the plugin, you can edit text and messages in this file. -default-language: en-US -# Sets the amount of hours a listing is active before being automatically cancelled and expired. -expire-interval: 48 -# Sets the price it costs to list one item on the auction house. -listing-price: 0 -# Allows or blocks players in creative mode from selling items. -creative-sale: false -# The maximum amount of listings a player can have. -max-items: 45 -# Items that cannot be listed on the auction. Refer to https://minecraftitemids.com/ or https://minecraft-ids.grahamedgecombe.com/ for a list of item ids. -blacklist: - - '1000' #Example items, these items dont exist in MC, but you should use ones that do if you want. - - '1001:12' +Feature-packed AuctionHouse plugin for PocketMine-MP + +## Overview +AuctionHouse allows players to list their items for sale and purchase items that others have listed for sale. + +![AuctionHouse](https://github.com/Shock95x/AuctionHouse/blob/master/img/auctionhouse.png) +--- +## Features +>- Chest GUI +>- Config (See below) +>- Multi-lang support +>- Custom Events +>- Economy plugin support (EconomyAPI as of now) +>- MySQL and SQLite database support +>- Customizable messages +- And more coming soon! +--- +## Download +Check the [releases tab](https://github.com/Shock95x/AuctionHouse/releases) or [PoggitCI](https://poggit.pmmp.io/ci/Shock95x/AuctionHouse/AuctionHouse/) + +--- +## Config +```yaml +--- +# DO NOT EDIT THIS VALUE, INTERNAL USE ONLY. +config-version: 3 +# Sets the prefix for this plugin. +prefix: "[&l&6Auction House&r]" +# Minimum price required to create a listing +min-price: 0 +# Maximum price a listing can have (-1 = No limit) +max-price: -1 +# Sets the default language for the plugin, you can edit text and messages in this file. +default-language: en_US +# Sets the amount of hours a listing is active before being automatically cancelled and expired. +expire-interval: 48 +# Sets the price it costs to list one item on the auction house. +listing-price: 0 +# Allows or blocks players in creative mode from selling items. +creative-sale: false +# The maximum amount of listings a player can have. +max-items: 45 +# Items that cannot be listed on the auction. Refer to https://minecraftitemids.com/ or https://minecraft-ids.grahamedgecombe.com/ for a list of item ids. +blacklist: + - '1000' #Example items, these items dont exist in MC, but you should use ones that do if you want. + - '1001:12' - '12333:4' -... -``` ---- -## Commands - -| Command | Description | -| ------------- |:--------------| -| /ah | AuctionHouse main command, opens the shop menu if there are no specified parameters | -| /ah shop | Opens the shop menu | -| /ah sell **[price]** | Allows player to list items in their hand on the auction house. **[price]** is the amount that the player is listing the item to sell for | -| /ah listings | Shows all active listings of the player| -| /ah update | Allows player to reload the config and save the database (OP command) | -| /ah about | Shows AuctionHouse version the server is running and author of this plugin | ---- -## API -### Events -- [shock95x\auctionhouse\event\AuctionStartEvent](https://github.com/Shock95x/AuctionHouse/blob/master/src/AuctionHouse/event/AuctionStartEvent.php) -- [shock95x\auctionhouse\event\AuctionEndEvent](https://github.com/Shock95x/AuctionHouse/blob/master/src/AuctionHouse/event/AuctionEndEvent.php) +... +``` +--- +## Commands + +| Command | Description | +| ------------- |:--------------| +| /ah | AuctionHouse main command, opens the shop menu if there are no specified parameters | +| /ah shop | Opens the shop menu | +| /ah sell **[price]** | Allows player to list items in their hand on the auction house. **[price]** is the amount that the player is listing the item to sell for | +| /ah listings | Shows all active listings of the player| +| /ah update | Allows player to reload the config and save the database (OP command) | +| /ah about | Shows AuctionHouse version the server is running and author of this plugin | +--- +## API +### Events +- [shock95x\auctionhouse\event\AuctionStartEvent](https://github.com/Shock95x/AuctionHouse/blob/master/src/AuctionHouse/event/AuctionStartEvent.php) +- [shock95x\auctionhouse\event\AuctionEndEvent](https://github.com/Shock95x/AuctionHouse/blob/master/src/AuctionHouse/event/AuctionEndEvent.php) + +## Contributing +You can contribute to this project by creating a new language file and opening a PR! +### Supported languages +- [Shock95x](https://github.com/Shock95x) (English) +- [No4NaMe](https://github.com/No4NaMe) (Russian) \ No newline at end of file diff --git a/plugin.yml b/plugin.yml index 6a37bea..d8ba036 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: AuctionHouse main: shock95x\auctionhouse\AuctionHouse -version: 1.0.9 +version: 1.1.0 api: 3.0.0 author: Shock95x softdepend: [EconomyAPI] diff --git a/resources/config.yml b/resources/config.yml index bec4ba9..984df9b 100644 --- a/resources/config.yml +++ b/resources/config.yml @@ -1,8 +1,12 @@ --- # DO NOT EDIT THIS VALUE, INTERNAL USE ONLY. -config-version: 2 +config-version: 3 # Sets the prefix for this plugin. prefix: "[&l&6Auction House&r]" +# Minimum price required to create a listing +min-price: 0 +# Maximum price a listing can have (-1 = No limit) +max-price: -1 # Sets the default language for the plugin, you can edit text and messages in this file. default-language: en_US # Sets the amount of hours a listing is active before being automatically cancelled and expired. diff --git a/resources/language/en_US.yml b/resources/language/en_US.yml index 7c5282a..e7b3a69 100644 --- a/resources/language/en_US.yml +++ b/resources/language/en_US.yml @@ -31,6 +31,7 @@ cannot-afford: "&6You do not have enough money to buy this item." item-blacklisted: "&cThat item is not allowed to be put on the auction house!" invalid-balance: "&cYou do not have enough money to list an auction." listing-gone: "&cThis listing no longer exists." +price-range: "&cInvalid price range" #@min, @max # Items in the menu UI listed-item: diff --git a/resources/language/ru_RU.yml b/resources/language/ru_RU.yml new file mode 100644 index 0000000..8d1b6dd --- /dev/null +++ b/resources/language/ru_RU.yml @@ -0,0 +1,163 @@ +--- +# Refer to https://minecraft.gamepedia.com/Formatting_codes for formatting codes, you can replace the '§' symbol with a '&' + +# The titles of the Auction House UI +menu-name: "&l&6Аукционный дом" +listings-menu-name: "&6Активные списки" +expired-menu-name: "&6Отменен / Истекшие списки" +purchase-menu-name: "Подтвердите покупку" + +# Chat messages +item-purchased: "&eТовар Куплен&e!" +buyer-purchased: "&6%покупатель% &eприобрёл ваш предмет за &6$%price%&e!" +item-listed: "&2Вы перечислили &d@item &r&d(x@amount) &2за &d@price. Тип &e/ah listings &dпросмотреть все ваши аукционы" +cancelled-item: "&eВы &6Отменили &eаукцион. Возврат отмененных и просроченных товаров по адресу &6/ah expired&e." +cancelled-purchase: "&cВы отменили эту покупку" +admin-removed: "&eСписок удален." +purchased-item: "&2Вы купили &d@item &r&d(x@amount) &2за &d@price" #@player, @item, @price, @amount +seller-message: "&e@Игрок приобрел @item (x@amount) ваш предмет за &d@price!" #@player, @item, @price, @amount +returned-item: "&2Вы удалили &d@item &r&d(x@amount) &2 из аукционного дома." #@item, @amount + +# Error messages +in-creative: "&cВы не можете продавать предметы в творческом режиме." +max-listings: "&cВы не можете иметь более 45 активных аукционов." +invalid-price: "&cНеверная цена." +no_empty: "&cВаш инвентарь пуст." +not-enough-space: "Недостаточно места в инвентаре" +self-purchase: "&cВы не можете купить свои собственные вещи на аукционе!" +item-gone: "Этого предмета больше не существует" +no-item: "&cВы должны держать предмет в руке!" +cannot-afford: "&6У вас недостаточно денег, чтобы купить этот предмет." +item-blacklisted: "&cЭтот предмет не может быть выставлен на аукцион!" +invalid-balance: "&cУ вас недостаточно денег, чтобы выставить предмет на аукцион." +listing-gone: "&cЭтого списка больше не существует." + +# Items in the menu UI +listed-item: + # %price% = Цена листинга + # %seller% = Имя продавца + # %expire% = Время до истечения срока листинга + - "&7-------------------------" + - "&aНажмите здесь, чтобы купить." + - "" + - "&9Цена: &e$%price%" + - "&9Продавец: &e%seller%" + - "&9Истекать: &e%time%" + - "&7-------------------------" +your-listed-item: + # %price% = Цена аукциона + # %expire% = Время до истечения срока аукциона + - "&7-------------------------" + - "&cНажмите здесь, чтобы отменить." + - "" + - "&9Цена: &e$%price%" + - "&9Истекает: &e%time%" + - "&7-------------------------" +view-listed-items: + # %selling% = Количество активных аукционов + id: 264 + name: "&6Предметы, которые вы продаете" + lore: + - "&aНажмите здесь, чтобы просмотреть все предметы, которые вы" + - "&aв данный момент продаете на аукционе." + - "" + - "&9Продажа: &e%selling%" +view-expired-items: + # %expired% = Количество истекших аукционов + id: 394 + name: "&6Собрать просроченные / отмененные предметы" + lore: + - "&r&aНажмите здесь, чтобы просмотреть и собрать все" + - "&aЭлементы, которые вы отменили или просрочели." + - "" + - "&9Предметы для сбора: &e%expired%" +previous-page: + id: "339" + name: "&a<- Предыдущая страница" + lore: + - "Перейти на предыдущую страницу" +next-page: + id: "339" + name: "&aСледующая Страница ->" + lore: + - "Перейти на следующую страницу" +back-button: + id: "339" + name: "&6Назад" + lore: +sell-description: + id: "388" + name: "&6Как продать предмет" + lore: + - "&aЧтобы выставить предмет на аукцион, просто удерживайте" + - "&aпредмет в вашей руке и введите &b/ah sell <цена>&a." +main-description: + id: "340" + name: "&6Что это за страница?" + lore: + - "&aЭто аукционный дом, здесь можно" + - "&aсписок предметов для продажи и покупки предметов" + - "&aчто другие выставили на продажу." + - "" + - "&aАукцион также отличный способ сделать" + - "&aденьги от продажи других товаров" + - "&aигроки могут быть заинтересованы в покупке." +main-stats: + # %page% = Текущая страница + # %max% = Макс страница + # %total% = Общее количество товаров + id: "54" + name: "&l&6Аукционный дом" + lore: + - "&aСтраница %page%/%max%" + - "&7Всего &b%total% &7предметов" + - "Нажмите, чтобы обновить страницу" +listings-description: + id: "340" + name: "&6Что это за страница?" + lore: + - "&aЭто ваши текущие списки, все" + - "&aпредметы, которые вы сейчас перечислили на" + - "&aаукционный дом отображаются здесь." + - "" + - "&aВы можете отменить и просмотреть свои списки" + - "&aистекает время здесь." +listings-stats: + # %page% = Текущая страница + # %max% = Последняя страница + # %total% = Общее количество объявлений + id: "54" + name: "&l&6Объявления" + lore: + - "&aСтраница %page%/%max%" + - "&7Всего &b%total% &7предметов" +expired-description: + id: "340" + name: "&6Что это за страница?" + lore: + - "&aЭта страница содержит все ваши отмененные" + - "&aпредметы с истекшим сроком, когда список отменен" + - "&aили истек срок действия, вы можете нажать возврат, что бы" + - "&aвернуться назад из этого меню." + - "" + - "&aПросто нажмите на элемент, и если у вас достаточно" + - "&aв инвентаре вы получите предмет." +expired-stats: + # %page% = Текущая страница + # %max% = Последняя страница + # %total% = Общее количество предметов + id: "152" + name: "&l&6Истекший" + lore: + - "&aСтраница %page%/%max%" + - "&7Всего &b%total% &7предметов" +purchase-confirm: + name: "&aПодтвердите покупку" +purchase-cancel: + name: "&cОтменить покупку" +purchaseItem: + lore: + - "" + - "&9Цена: &e$%price%" + - "&9Продавец: &e%seller%" +... \ No newline at end of file diff --git a/resources/statements/mysql.sql b/resources/statements/mysql.sql new file mode 100644 index 0000000..2c66827 --- /dev/null +++ b/resources/statements/mysql.sql @@ -0,0 +1,39 @@ +-- #!mysql +-- #{ auctionhouse + +-- # { init +CREATE TABLE IF NOT EXISTS auctions( + uuid VARCHAR, + username VARCHAR, + price INT, + nbt BLOB, + end_time INT, + expired BOOLEAN DEFAULT FALSE, + id INT PRIMARY KEY); +-- # } + +-- # { fetch + +-- # { all +SELECT * FROM auctions; +-- # } +-- # } + +-- # { delete +-- # :id string +DELETE FROM auctions +WHERE id = :id; +-- # } + +-- # { insert +-- # :uuid string +-- # :username string +-- # :price int +-- # :nbt string +-- # :id int +-- # :end_time int +-- # :expired bool +REPLACE INTO auctions(uuid, username, price, nbt, id, end_time, expired) VALUES (:uuid, :username, :price, :nbt, :id, :end_time, :expired) +-- # } + +-- # } \ No newline at end of file diff --git a/src/shock95x/auctionhouse/AuctionHouse.php b/src/shock95x/auctionhouse/AuctionHouse.php index 784074e..58abfff 100644 --- a/src/shock95x/auctionhouse/AuctionHouse.php +++ b/src/shock95x/auctionhouse/AuctionHouse.php @@ -2,7 +2,7 @@ namespace shock95x\auctionhouse; use DateTime; -use Exception; +use muqsit\invmenu\session\PlayerManager; use shock95x\auctionhouse\database\DataHolder; use shock95x\auctionhouse\menu\MenuHandler; use shock95x\auctionhouse\database\Database; @@ -11,8 +11,6 @@ use shock95x\auctionhouse\utils\Settings; use JackMD\ConfigUpdater\ConfigUpdater; use JackMD\UpdateNotifier\UpdateNotifier; -use pocketmine\inventory\Inventory; -use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; use pocketmine\plugin\PluginBase; @@ -41,7 +39,7 @@ class AuctionHouse extends PluginBase { public function onLoad() { $this->saveDefaultConfig(); UpdateNotifier::checkUpdate($this, $this->getDescription()->getName(), $this->getDescription()->getVersion()); - ConfigUpdater::checkUpdate($this, $this->getConfig(), "config-version", 2); + ConfigUpdater::checkUpdate($this, $this->getConfig(), "config-version", 3); } public function onEnable() : void { @@ -91,6 +89,7 @@ public function onEnable() : void { public function onDisable() { $this->database->save(); + $this->database->close(); } /** @@ -148,51 +147,47 @@ public function getMessage(?Player $sender, $key, bool $return = false, $prefix return ""; } - /** - * Sends the Auction House menu to specified player - * - * @param Player $player - * @param Inventory $currentMenu - * @param int $n - * @return bool - * @throws Exception - */ - public function sendAHMenu(Player $player, $currentMenu = null, int $n = 1) { + public function sendAHMenu(Player $player, int $n = 1) { MenuHandler::setViewingMenu($player, MenuHandler::AUCTION_MENU); $list = DataHolder::getListings(); if($n < 1) { $size = count($list); - $n = $size / 45; - if ($size % 45 > 0) { - ++$n; - } - } + $n = $size / 45; + if ($size % 45 > 0) { + ++$n; + } + } $size2 = count($list); - $n2 = ($n - 1) * 45; - $n3 = ($n2 + 44 >= $size2) ? ($size2 - 1) : ($n * 45 - 1); - if ($n3 - $n2 + 1 < 1 && $n != 1) { - $this->sendAHMenu($player, null, 1); - return false; - } - $n4 = 0; - for($i = 0; $i < 45; ++$i) { - if($currentMenu != null) $currentMenu->setItem($i, Item::get(Item::AIR)); - } - $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST) - ->readonly() - ->sessionize() - ->setListener([$this->menuHandler, "handleItemSelection"]); + $n2 = ($n - 1) * 45; + $n3 = ($n2 + 44 >= $size2) ? ($size2 - 1) : ($n * 45 - 1); + if ($n3 - $n2 + 1 < 1 && $n != 1) { + $this->sendAHMenu($player, 1); + return false; + } + $n4 = 0; + + $menu = null; + $newMenu = false; + if(PlayerManager::get($player)->getCurrentMenu() == null) { + $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST)->readonly(); + $newMenu = true; + } else { + $menu = PlayerManager::get($player)->getCurrentMenu(); + $menu->getInventoryForPlayer($player)->clearAll(); + } + $menu->setListener([$this->menuHandler, "handleItemSelection"]); + $inventory = $menu->getInventoryForPlayer($player); + for($j = $n2; $j <= $n3; ++$j) { ++$n4; if(!isset($list[$j])) return false; $auction = $list[$j]; $item = clone $auction->getItem(); - $endTime = (new DateTime())->diff((new DateTime())->setTimestamp($auction->getEndTime())); $tag = $item->hasCompoundTag() ? $item->getNamedTag() : new CompoundTag(); $tag->setLong("marketId", $auction->getMarketId()); $item->setCompoundTag($tag)->setCustomName(TextFormat::RESET . $item->getName() . "\n" . TextFormat::GRAY . str_repeat("-", 25) . "\n" . TextFormat::GREEN . "Click here to purchase.\n\n" . TextFormat::BLUE . "Price: " . TextFormat::YELLOW . $this->economyProvider->getMonetaryUnit() . $auction->getPrice() . "\n" . TextFormat::BLUE . "Seller: " . TextFormat::YELLOW . $auction->getSeller() . "\n" . TextFormat::BLUE . "Expires: " . TextFormat::YELLOW . ($endTime->days * 24 + $endTime->h) . ":" . $endTime->i . "\n" . TextFormat::GRAY . str_repeat("-", 25)); - $menu->getInventory($player)->addItem($item); + $inventory->addItem($item); } Pagination::setPage($player, $n); $total = count($list); @@ -200,17 +195,17 @@ public function sendAHMenu(Player $player, $currentMenu = null, int $n = 1) { for($i = 0; $i < $total; $i += 45) $max++; if($max == 0) $max = 1; $p = Pagination::getPage($player); - MenuRenderer::setAuctionItems($player, $menu->getInventory($player), $p, $max, $total, count((array) DataHolder::getListingsByPlayer($player)), count((array)DataHolder::getListingsByPlayer($player, true))); - $menu->send($player, $this->getMessage($player, "menu-name", true, false)); + MenuRenderer::setAuctionItems($player, $inventory, $p, $max, $total, count((array) DataHolder::getListingsByPlayer($player)), count((array)DataHolder::getListingsByPlayer($player, true))); + + if($newMenu) $menu->send($player, $this->getMessage($player, "menu-name", true, false)); return true; } /** * @param Player $player - * @param Inventory|null $currentMenu * @param int $n */ - public function sendExpired(Player $player, Inventory $currentMenu = null, int $n = 1) : void { + public function sendExpired(Player $player, int $n = 1) : void { MenuHandler::setViewingMenu($player, MenuHandler::EXPIRED_MENU); $list = DataHolder::getListingsByPlayer($player, true); if($n < 1) { @@ -222,17 +217,23 @@ public function sendExpired(Player $player, Inventory $currentMenu = null, int $ $n2 = ($n - 1) * 45; $n3 = ($n2 + 44 >= $size2) ? ($size2 - 1) : ($n * 45 - 1); if($n3 - $n2 + 1 < 1 && $n != 1) { - $this->sendExpired($player, null, 1); + $this->sendExpired($player, 1); return; } $n4 = 0; - for($i = 0; $i < 45; ++$i) { - if($currentMenu != null) $currentMenu->setItem($i, Item::get(Item::AIR)); + + $menu = null; + $newMenu = false; + if(PlayerManager::get($player)->getCurrentMenu() == null) { + $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST)->readonly(); + $newMenu = true; + } else { + $menu = PlayerManager::get($player)->getCurrentMenu(); + $menu->getInventoryForPlayer($player)->clearAll(); } - $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST) - ->readonly() - ->sessionize() - ->setListener([$this->menuHandler, "handleExpired"]); + + $menu->setListener([$this->menuHandler, "handleExpired"]); + $inventory = $menu->getInventoryForPlayer($player); for($j = $n2; $j <= $n3; ++$j) { ++$n4; if(!isset($list[$j])) return; @@ -241,7 +242,7 @@ public function sendExpired(Player $player, Inventory $currentMenu = null, int $ $tag = $item->hasCompoundTag() ? $item->getNamedTag() : new CompoundTag(); $tag->setLong("marketId", $auction->getMarketId()); $item->setCompoundTag($tag)->setCustomName(TextFormat::RESET . $item->getName() . "\n" . TextFormat::GRAY . str_repeat("-", 25) . "\n" . TextFormat::GREEN . "Click here to receive item.\n\n" . TextFormat::BLUE . "Price: " . TextFormat::YELLOW . $this->economyProvider->getMonetaryUnit() . $auction->getPrice() . "\n" . TextFormat::GRAY . str_repeat("-", 25)); - $menu->getInventory($player)->addItem($item); + $inventory->addItem($item); } Pagination::setPage($player, $n); $total = count($list); @@ -249,16 +250,16 @@ public function sendExpired(Player $player, Inventory $currentMenu = null, int $ for($i = 0; $i < $total; $i += 45) $max++; if($max == 0) $max = 1; $p = Pagination::getPage($player); - menu\MenuRenderer::setExpiredItems($player, $menu->getInventory($player), $p, $max, $total); - $menu->send($player, $this->getMessage($player, "expired-menu-name", true, false)); + MenuRenderer::setExpiredItems($player, $inventory, $p, $max, $total); + + if($newMenu) $menu->send($player, $this->getMessage($player, "expired-menu-name", true, false)); } /** * @param Player $player - * @param Inventory|null $currentMenu * @param int $n */ - public function sendListings(Player $player, Inventory $currentMenu = null, int $n = 1) : void { + public function sendListings(Player $player, int $n = 1) : void { MenuHandler::setViewingMenu($player, MenuHandler::LISTINGS_MENU); $list = DataHolder::getListingsByPlayer($player); if($n < 1) { @@ -270,19 +271,26 @@ public function sendListings(Player $player, Inventory $currentMenu = null, int $n2 = ($n - 1) * 45; $n3 = ($n2 + 44 >= $size2) ? ($size2 - 1) : ($n * 45 - 1); if($n3 - $n2 + 1 < 1 && $n != 1) { - $this->sendListings($player, null, 1); + $this->sendListings($player, 1); return; } $n4 = 0; - for($i = 0; $i < 45; ++$i) { - if($currentMenu != null) $currentMenu->setItem($i, Item::get(Item::AIR)); + $menu = null; + $newMenu = false; + if(PlayerManager::get($player)->getCurrentMenu() == null) { + $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST)->readonly(); + $newMenu = true; + } else { + $menu = PlayerManager::get($player)->getCurrentMenu(); + $menu->getInventoryForPlayer($player)->clearAll(); + /*for($i = 0; $i < 45; ++$i) { + $menu->getInventory($player)>setItem($i, Item::get(Item::AIR)); + }*/ } - - $menu = InvMenu::create(InvMenu::TYPE_DOUBLE_CHEST) - ->readonly() - ->sessionize() - ->setListener([$this->menuHandler, "handleListings"]); + $menu->setListener([$this->menuHandler, "handleListings"]); + $inventory = $menu->getInventoryForPlayer($player); + for($j = $n2; $j <= $n3; ++$j) { ++$n4; if(!isset($list[$j])) return; @@ -291,7 +299,7 @@ public function sendListings(Player $player, Inventory $currentMenu = null, int $tag = $item->hasCompoundTag() ? $item->getNamedTag() : new CompoundTag(); $tag->setLong("marketId", $auction->getMarketId()); $item->setCompoundTag($tag)->setCustomName(TextFormat::RESET . $item->getName() . "\n" . TextFormat::GRAY . str_repeat("-", 25) . "\n" . TextFormat::RED . "Click here to remove listing\n\n" . TextFormat::BLUE . "Price: " . TextFormat::YELLOW . $this->economyProvider->getMonetaryUnit() . $auction->getPrice() . "\n" . TextFormat::GRAY . str_repeat("-", 25)); - $menu->getInventory($player)->addItem($item); + $inventory->addItem($item); } Pagination::setPage($player, $n); $total = count($list); @@ -299,7 +307,10 @@ public function sendListings(Player $player, Inventory $currentMenu = null, int for($i = 0; $i < $total; $i += 45) $max++; if($max == 0) $max = 1; $p = Pagination::getPage($player); - MenuRenderer::setListingItems($player, $menu->getInventory($player), $p, $max, $total); - $menu->send($player, $this->getMessage($player, "listings-menu-name", true, false)); + MenuRenderer::setListingItems($player, $inventory, $p, $max, $total); + if($newMenu) $menu->send($player, $this->getMessage($player, "listings-menu-name", true, false)); } + + /*protected function getPlayerMenu(Player $player) : InvMenu { + }*/ } diff --git a/src/shock95x/auctionhouse/EventListener.php b/src/shock95x/auctionhouse/EventListener.php index 49d2407..ab3faca 100644 --- a/src/shock95x/auctionhouse/EventListener.php +++ b/src/shock95x/auctionhouse/EventListener.php @@ -3,7 +3,7 @@ use shock95x\auctionhouse\menu\MenuHandler; use shock95x\auctionhouse\utils\Pagination; -use muqsit\invmenu\inventories\BaseFakeInventory; +use muqsit\invmenu\inventory\InvMenuInventory; use pocketmine\event\Listener; use pocketmine\event\inventory\InventoryCloseEvent; @@ -18,12 +18,12 @@ class EventListener implements Listener{ * * @param AuctionHouse $loader */ - public function __construct(AuctionHouse $loader){ + public function __construct(AuctionHouse $loader) { $this->loader = $loader; } public function onInventoryClose(InventoryCloseEvent $event) { - if($event->getInventory() instanceof BaseFakeInventory) { + if($event->getInventory() instanceof InvMenuInventory) { Pagination::setPage($event->getPlayer(), 1); MenuHandler::setViewingMenu($event->getPlayer(), -1); } diff --git a/src/shock95x/auctionhouse/commands/AHCommand.php b/src/shock95x/auctionhouse/commands/AHCommand.php index e6fee24..030ff27 100644 --- a/src/shock95x/auctionhouse/commands/AHCommand.php +++ b/src/shock95x/auctionhouse/commands/AHCommand.php @@ -38,7 +38,7 @@ public function __construct(AuctionHouse $plugin) { * @param string $commandLabel * @param string[] $args * - * @return mixed + * @return bool * @throws Exception */ public function execute(CommandSender $sender, string $commandLabel, array $args): bool { @@ -93,6 +93,10 @@ public function execute(CommandSender $sender, string $commandLabel, array $args $this->plugin->getMessage($sender, "invalid-balance"); return false; } + if($args[1] < Settings::getMinPrice() || ($args[1] > Settings::getMaxPrice() && Settings::getMaxPrice() != -1)) { + $sender->sendMessage(str_replace(["@min", "@max"], [Settings::getMinPrice(), Settings::getMaxPrice()], $this->plugin->getMessage($sender, "price-range", true))); + return false; + } if($listingPrice != 0) $this->getEconomy()->subtractMoney($sender, $listingPrice); $sender->getInventory()->removeItem($item); DataHolder::addListing($sender, (int) $args[1], (new BigEndianNBTStream())->writeCompressed($item->nbtSerialize())); diff --git a/src/shock95x/auctionhouse/database/DataHolder.php b/src/shock95x/auctionhouse/database/DataHolder.php index 52f25a0..29b9444 100644 --- a/src/shock95x/auctionhouse/database/DataHolder.php +++ b/src/shock95x/auctionhouse/database/DataHolder.php @@ -12,7 +12,7 @@ class DataHolder { /** @var Listing[] */ - private static $listings = array(); + private static $listings; private static $database; public function __construct(Database $database) { @@ -20,12 +20,14 @@ public function __construct(Database $database) { } public function loadListings() { + self::$listings = array(); Await::f2c(function () { $rows = (array) yield self::$database->fetchAll(); foreach($rows as $listing) { self::$listings[] = new Listing($listing, self::$database->getParser()); } }); + DataHolder::$database->getConnector()->waitAll(); AuctionHouse::getInstance()->getScheduler()->scheduleRepeatingTask(new ListingExpireTask(DataHolder::$database), 6000); } @@ -52,7 +54,11 @@ public static function getListingsByPlayer(Player $player, bool $expired = false return $array; } - public static function getListingById(int $id) { + /** + * @param int $id + * @return Listing + */ + public static function getListingById(int $id) : Listing { foreach((array) self::$listings as $listing) { if($listing->getMarketId() == $id) { return $listing; diff --git a/src/shock95x/auctionhouse/database/Database.php b/src/shock95x/auctionhouse/database/Database.php index 59f0e0b..6077df6 100644 --- a/src/shock95x/auctionhouse/database/Database.php +++ b/src/shock95x/auctionhouse/database/Database.php @@ -41,13 +41,15 @@ public function __construct(AuctionHouse $plugin, Config $config) { public function connect() : Database { try { $this->database = libasynql::create($this->plugin, $this->config->get("database"), [ - "sqlite" => "statements\sqlite.sql" - //"mysql" => "statements\mysql.sql" + "sqlite" => "statements/sqlite.sql", + "mysql" => "statements/mysql.sql" ]); $this->database->executeGeneric(Query::INIT); } catch(SqlError $error) { $this->plugin->getLogger()->error($error->getMessage()); } + $this->database->waitAll(); + $this->parser = BinaryStringParser::fromDatabase($this->config->get("database")["type"]); $this->holder = new DataHolder($this); $this->holder->loadListings(); @@ -60,7 +62,6 @@ public function getConnector() : DataConnector { protected function asyncSelect(string $query, array $args = []): Generator { $this->database->executeSelect($query, $args, yield, yield Await::REJECT); - return yield Await::ONCE; } @@ -84,14 +85,14 @@ public function save() { * @param bool $expired * @param int|null $id */ - public function insert(string $uuid, string $username, int $price, string $nbt, int $endTime, bool $expired = false, int $id = null) { + public function insert(string $uuid, string $username, int $price, string $nbt, int $endTime, bool $expired = false, $id = null) { $this->database->executeInsert(Query::INSERT, [ "uuid" => $uuid, "username" => $username, "price" => $price, "nbt" => $this->parser->encode($nbt), - "end_time" => $endTime, "id" => $id == null ? time() : $id, + "end_time" => $endTime, "expired" => $expired ]); } @@ -106,7 +107,10 @@ public function deleteFromId(string $id) { } public function close() { - if(isset($this->database)) $this->database->close(); + if(isset($this->database)) { + $this->database->waitAll(); + $this->database->close(); + } } public function getParser() : BinaryStringParserInstance { diff --git a/src/shock95x/auctionhouse/menu/MenuHandler.php b/src/shock95x/auctionhouse/menu/MenuHandler.php index 84a9c48..d2c0dce 100644 --- a/src/shock95x/auctionhouse/menu/MenuHandler.php +++ b/src/shock95x/auctionhouse/menu/MenuHandler.php @@ -30,6 +30,7 @@ class MenuHandler { public function __construct(AuctionHouse $plugin) { $this->plugin = $plugin; + self::$menuOpen = []; } public static function setViewingMenu(Player $player, int $menu) { @@ -95,28 +96,32 @@ public function handleExpired(Player $player, Item $itemClicked, Item $itemClick public function handleItemSelection(Player $player, Item $itemClicked, Item $itemClickedWith, SlotChangeAction $action) : bool { $inventory = $action->getInventory(); if($itemClicked->getNamedTag()->hasTag("refresh")) { - $this->getPlugin()->sendAHMenu($player, $inventory, 2); + $this->getPlugin()->sendAHMenu($player, 2); return false; } if($itemClicked->getNamedTag()->hasTag("listings")) { - $this->getPlugin()->sendListings($player, null); + $this->getPlugin()->sendListings($player); return false; } if($itemClicked->getNamedTag()->hasTag("expired")) { - $this->getPlugin()->sendExpired($player, null); + $this->getPlugin()->sendExpired($player); return false; } + if($itemClicked->getNamedTag()->hasTag("pagination")) { + $page = $itemClicked->getNamedTag()->getByte("pagination"); + $this->handlePagination($player, $page); + return true; + } if($action->getSlot() <= 44 && $itemClicked->getNamedTag()->hasTag("marketId")) { $player->removeWindow($inventory); $id = $itemClicked->getNamedTag()->getLong("marketId"); $menu = InvMenu::create(InvMenu::TYPE_CHEST) ->readonly() - ->sessionize() ->setName($this->getPlugin()->getMessage($player, "purchase-menu-name", true, false)) ->setListener([$this, "handlePurchase"]); - $newInv = $menu->getInventory($player); + $newInv = $menu->getInventoryForPlayer($player); $item = clone $itemClicked; $newInv->setItem(13, $item); @@ -134,11 +139,6 @@ public function handleItemSelection(Player $player, Item $itemClicked, Item $ite $this->getPlugin()->getScheduler()->scheduleDelayedTask(new MenuDelayTask($player, $menu), 10); return true; } - if($itemClicked->getNamedTag()->hasTag("pagination")) { - $page = $itemClicked->getNamedTag()->getByte("pagination"); - $this->handlePagination($player, $page); - return true; - } return true; } @@ -147,39 +147,39 @@ public function handlePagination(Player $player, int $pagination) { // todo: han case self::AUCTION_MENU: switch($pagination) { case Pagination::BACK: - $this->plugin->sendAHMenu($player, null, Pagination::getPage($player) - 1); + $this->plugin->sendAHMenu($player, Pagination::getPage($player) - 1); break; case Pagination::NEXT: - $this->plugin->sendAHMenu($player, null, Pagination::getPage($player) + 1); + $this->plugin->sendAHMenu($player, Pagination::getPage($player) + 1); break; case Pagination::REFRESH: - $this->plugin->sendAHMenu($player, null, Pagination::getPage($player)); + $this->plugin->sendAHMenu($player, Pagination::getPage($player)); break; } break; case self::LISTINGS_MENU: switch($pagination) { case Pagination::BACK: - $this->plugin->sendListings($player, null, Pagination::getPage($player) - 1); + $this->plugin->sendListings($player, Pagination::getPage($player) - 1); break; case Pagination::NEXT: - $this->plugin->sendListings($player, null, Pagination::getPage($player) + 1); + $this->plugin->sendListings($player, Pagination::getPage($player) + 1); break; case Pagination::REFRESH: - $this->plugin->sendListings($player, null, Pagination::getPage($player)); + $this->plugin->sendListings($player, Pagination::getPage($player)); break; } break; case self::EXPIRED_MENU: switch($pagination) { case Pagination::BACK: - $this->plugin->sendExpired($player, null, Pagination::getPage($player) - 1); + $this->plugin->sendExpired($player, Pagination::getPage($player) - 1); break; case Pagination::NEXT: - $this->plugin->sendExpired($player, null, Pagination::getPage($player) + 1); + $this->plugin->sendExpired($player, Pagination::getPage($player) + 1); break; case Pagination::REFRESH: - $this->plugin->sendExpired($player, null, Pagination::getPage($player)); + $this->plugin->sendExpired($player, Pagination::getPage($player)); break; } break; diff --git a/src/shock95x/auctionhouse/utils/Settings.php b/src/shock95x/auctionhouse/utils/Settings.php index 835441c..78bb326 100644 --- a/src/shock95x/auctionhouse/utils/Settings.php +++ b/src/shock95x/auctionhouse/utils/Settings.php @@ -12,6 +12,8 @@ class Settings { private static $listingPrice = 0; private static $creativeSale = false; private static $maxItems = 45; + private static $minPrice = 0; + private static $maxPrice = -1; private static $blacklist = []; public static function init(Config $config) { @@ -21,6 +23,8 @@ public static function init(Config $config) { self::$listingPrice = $config->get("listing-price"); self::$creativeSale = $config->get("creative-sale"); self::$maxItems = $config->get("max-items"); + self::$minPrice = $config->get("min-price"); + self::$maxPrice = $config->get("max-price"); self::$blacklist = $config->getNested("blacklist"); } @@ -66,6 +70,13 @@ public static function getMaxItems(): int { return self::$maxItems; } + public static function getMinPrice() : int { + return self::$minPrice; + } + + public static function getMaxPrice() : int { + return self::$maxPrice; + } /** * @return Item[] */