<?php __HALT_COMPILER(); ?>
Õ                     src/aieuo/itemtrade/Main.php1.  Èªo]1.  Ê‚¶      $   src/aieuo/itemtrade/ItemDataBase.phpê  Èªo]ê  —Èoô¶      	   README.md   Èªo]   e•’u¶      
   plugin.yml¿   Èªo]¿   ’—*e¶      <?php

namespace aieuo\itemtrade;

use pocketmine\event\Listener;
use pocketmine\plugin\PluginBase;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
use pocketmine\utils\Config;
use pocketmine\item\Item;
use pocketmine\event\player\PlayerJoinEvent;
use onebone\economyapi\EconomyAPI;

class Main extends PluginBase implements Listener {
    public function onEnable() {
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
        $items = new Config($this->getDataFolder()."items.yml", Config::YAML, []);
        $this->buylog = new Config($this->getDataFolder()."buylog.yml", Config::YAML, []);
        $this->selllog = new Config($this->getDataFolder()."selllog.yml", Config::YAML, []);
        $this->db = new ItemDataBase($this, $items, $this->buylog, $this->selllog);
    }

    public function onDisable() {
        $this->db->save();
    }

    public function join(PlayerJoinEvent $event) {
        $player = $event->getPlayer();
        if($this->buylog->exists($player->getName())) {
            $log = $this->buylog->get($player->getName());
            foreach($log as $id => $values) {
                foreach($values as $value) {
                    $player->sendMessage("$".$value["price"]."ã§æ³¨æ–‡ã—ãŸ".$id."ãŒ".$value["count"]."å€‹è³¼å…¥ã§ãã¾ã—ãŸ");
                    $ids = explode(":", $id);
                    $item = Item::get($ids[0], $ids[1], $value["count"]);
                    $player->getInventory()->addItem($item);
                }
            }
            $this->buylog->remove($player->getName());
        }
        if($this->selllog->exists($player->getName())) {
            $log = $this->selllog->get($player->getName());
            $price = 0;
            foreach($log as $id => $values) {
                foreach($values as $value) {
                    $player->sendMessage("$".$value["price"]."ã§æ³¨æ–‡ã—ãŸ".$id."ãŒ".$value["count"]."å€‹å£²å´ã§ãã¾ã—ãŸ");
                    $price += $value["count"] * $value["price"];
                }
            }
            EconomyAPI::getInstance()->addMoney($player->getName(), $price);
            $this->selllog->remove($player->getName());
        }
    }

    public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool {
        $item = $sender->getInventory()->getItemInHand();
        $form = [
            "type" => "form",
            "title" => "é¸æŠž",
            "content" => "Â§7ãƒœã‚¿ãƒ³ã‚’æŠ¼ã—ã¦ãã ã•ã„",
            "buttons" => [
                ["text" => "å£²ã‚‹"],
                ["text" => "è²·ã†"],
                ["text" => "ã‚­ãƒ£ãƒ³ã‚»ãƒ«"]
            ]
        ];
        $this->sendForm($sender, $form, [$this, "onMenu"]);
        return true;
    }

    public function onMenu($player, $data) {
        if($data === null) return;
        $item = $player->getInventory()->getItemInHand();
        switch ($data) {
            case 0:
                if($item->getId() === 0) {
                    $player->sendMessage("ãã®ã‚¢ã‚¤ãƒ†ãƒ ã¯å£²ã‚Œã¾ã›ã‚“");
                    return;
                }
                $buylist = $this->db->getBuy($item);
                $buylist = array_map(function($value) { return array_sum($value); }, $buylist);
                krsort($buylist);
                $buylist = array_slice($buylist, 0, 10, true);
                $list = [];
                foreach($buylist as $price => $value) {
                    $list[] = "$".$price." : ".$value."å€‹";
                }
                $form = [
                    "type" => "custom_form",
                    "title" => "å£²ã‚‹",
                    "content" => [
                        [
                            "type" => "label",
                            "text" => $item->getId().":".$item->getDamage()
                        ],
                        [
                            "type" => "input",
                            "text" => "å€‹æ•°",
                            "placeholder" => "1ä»¥ä¸Šã®æ•°å­—ã§"
                        ],
                        [
                            "type" => "input",
                            "text" => "å€¤æ®µ",
                            "placeholder" => "1ä»¥ä¸Šã®æ•°å­—ã§"
                        ],
                        [
                            "type" => "label",
                            "text" => "------è²·ã„æ³¨æ–‡------\n".implode("\n", $list)
                        ]
                    ]
                ];
                $this->sendForm($player, $form, [$this, "onSell"], new Item($item->getId(), $item->getDamage()));
                break;
            case 1:
                $selllist = $this->db->getSell($item);
                $selllist = array_map(function($value) { return array_sum($value); }, $selllist);
                ksort($selllist);
                $selllist = array_slice($selllist, 0, 10, true);
                $list = [];
                foreach($selllist as $price => $value) {
                    $list[] = "$".$price." : ".$value."å€‹";
                }
                $form = [
                    "type" => "custom_form",
                    "title" => "è²·ã†",
                    "content" => [
                        [
                            "type" => "input",
                            "text" => "id",
                            "placeholder" => "id:damage",
                            "default" => $item->getId().":".$item->getDamage()
                        ],
                        [
                            "type" => "input",
                            "text" => "å€‹æ•°",
                            "placeholder" => "1ä»¥ä¸Šã®æ•°å­—ã§"
                        ],
                        [
                            "type" => "input",
                            "text" => "å€¤æ®µ",
                            "placeholder" => "1ä»¥ä¸Šã®æ•°å­—ã§"
                        ],
                        [
                            "type" => "label",
                            "text" => "------å£²ã‚Šæ³¨æ–‡------\n".implode("\n", $list)
                        ]
                    ]
                ];
                $this->sendForm($player, $form, [$this, "onBuy"], new Item($item->getId(), $item->getDamage()));
                break;
        }
    }

    public function onSell($player, $data, $item) {
        if($data === null) return;
        $amount = (int)$data[1];
        $price = (int)$data[2];
        if($amount <= 0) {
            $player->sendMessage("å€‹æ•°ã¯1ä»¥ä¸Šã§æŒ‡å®šã—ã¦ãã ã•ã„");
            return;
        }
        if($price <= 0) {
            $player->sendMessage("å€¤æ®µã¯1ä»¥ä¸Šã§æŒ‡å®šã—ã¦ãã ã•ã„");
            return;
        }
        $item->setCount($amount);
        if(!$player->getInventory()->contains($item)) {
            $player->sendMessage("ã‚¢ã‚¤ãƒ†ãƒ ã‚’å¿…è¦ãªæ•°æŒã£ã¦ã„ã¾ã›ã‚“");
            return;
        }
        $sellable = $this->db->getSellableCount($item, $price);
        $form = [
            "type" => "modal",
            "title" => "å£²å´ç¢ºèª",
            "content" => "$".$price."ã§".$item->getId().":".$item->getDamage()."ã‚’æœ¬å½“ã«å£²ã‚Šã¾ã™ã‹?\n".$amount."å€‹ä¸­".$sellable."å€‹ä»Šã™ãå£²ã‚‹ã“ã¨ãŒã§ãã¾ã™",
            "button1" => "å£²ã‚‹",
            "button2" => "ã‚­ãƒ£ãƒ³ã‚»ãƒ«"
        ];
        $this->sendForm($player, $form, [$this, "onConfirmSell"], $item, $price);
    }

    public function onConfirmSell($player, $data, $item, $price) {
        if($data === null) return;
        if(!$data) {
            $player->sendMessage("ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã¾ã—ãŸ");
            return;
        }
        $remain = $this->db->onSell($player, $item, $price);
        $player->getInventory()->removeItem($item);
        $player->sendMessage(($item->getCount() - $remain)."å€‹å£²ã‚Šã¾ã—ãŸ");
        EconomyAPI::getInstance()->addMoney($player->getName(), ($item->getCount() - $remain) * $price);
        if($remain !== 0) {
            $item->setCount($remain);
            $this->db->addSell($player, $item, $price);
        }
    }

    public function onBuy($player, $data, $item) {
        if($data === null) return;
        $amount = (int)$data[1];
        $price = (int)$data[2];
        if($amount <= 0) {
            $player->sendMessage("å€‹æ•°ã¯1ä»¥ä¸Šã§æŒ‡å®šã—ã¦ãã ã•ã„");
            return;
        }
        if($price <= 0) {
            $player->sendMessage("å€¤æ®µã¯1ä»¥ä¸Šã§æŒ‡å®šã—ã¦ãã ã•ã„");
            return;
        }
        $item->setCount($amount);
        if(EconomyAPI::getInstance()->mymoney($player->getName()) < $price * $amount) {
            $player->sendMessage("ãŠé‡‘ãŒè¶³ã‚Šã¾ã›ã‚“");
            return;
        }
        $buyable = $this->db->getBuyableCount($item, $price);
        $form = [
            "type" => "modal",
            "title" => "è³¼å…¥ç¢ºèª",
            "content" => "$".$price."ã§".$item->getId().":".$item->getDamage()."ã‚’æœ¬å½“ã«è²·ã„ã¾ã™ã‹?\n".$amount."å€‹ä¸­".$buyable."å€‹ä»Šã™ãè²·ã†ã“ã¨ãŒã§ãã¾ã™",
            "button1" => "è²·ã†",
            "button2" => "ã‚­ãƒ£ãƒ³ã‚»ãƒ«"
        ];
        $this->sendForm($player, $form, [$this, "onConfirmBuy"], $item, $price);
    }

    public function onConfirmBuy($player, $data, $item, $price) {
        if($data === null) return;
        if(!$data) {
            $player->sendMessage("ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã¾ã—ãŸ");
            return;
        }
        $remain = $this->db->onBuy($player, $item, $price);
        $player->sendMessage(($item->getCount() - $remain)."å€‹è²·ã„ã¾ã—ãŸ");
        EconomyAPI::getInstance()->reduceMoney($player->getName(), $item->getCount() * $price);
        if($item->getCount() - $remain !== 0) {
            $item2 = Item::get($item->getId(), $item->getDamage(), $item->getCount() - $remain);
            $player->getInventory()->addItem($item2);
        }
        if($remain !== 0) {
            $item->setCount($remain);
            $this->db->addBuy($player, $item, $price);
        }
    }















    public function encodeJson($data){
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING | JSON_UNESCAPED_UNICODE);
        return $json;
    }

    public function sendForm($player, $form, $callable = null, ...$datas) {
        while(true) {
            $id = mt_rand(0, 999999999);
            if(!isset($this->forms[$id])) break;
        }
        $this->forms[$id] = [$callable, $datas];
        $pk = new ModalFormRequestPacket();
        $pk->formId = $id;
        $pk->formData = $this->encodeJson($form);
        $player->dataPacket($pk);
    }

    public function Receive(DataPacketReceiveEvent $event){
        $pk = $event->getPacket();
        $player = $event->getPlayer();
        if($pk instanceof ModalFormResponsePacket){
            if(isset($this->forms[$pk->formId])) {
                $json = str_replace([",]",",,"], [",\"\"]",",\"\","], $pk->formData);
                $data = json_decode($json);
                if(is_callable($this->forms[$pk->formId][0])) {
                    call_user_func_array($this->forms[$pk->formId][0], array_merge([$player, $data], $this->forms[$pk->formId][1]));
                }
                unset($this->forms[$pk->formId]);
            }
        }
    }
}<?php

namespace aieuo\itemtrade;

use pocketmine\Player;
use pocketmine\item\Item;
use pocketmine\utils\Config;
use onebone\economyapi\EconomyAPI;

class ItemDataBase {
    public function __construct(Main $owner, Config $items, Config $buylog, Config $selllog) {
        $this->owner = $owner;
        $this->items = $items;
        $this->buylog = $buylog;
        $this->selllog = $selllog;
    }

    public function save() {
        $this->items->save();
        $this->buylog->save();
        $this->selllog->save();
    }

    public function getSell(Item $item) {
        $list = $this->items->get($item->getId().":".$item->getDamage(), ["sell" => [], "buy" => []]);
        if(!isset($list["sell"])) $list["sell"] = [];
        return $list["sell"];
    }


    public function getBuy(Item $item) {
        $list = $this->items->get($item->getId().":".$item->getDamage(), ["sell" => [], "buy" => []]);
        if(!isset($list["buy"])) $list["buy"] = [];
        return $list["buy"];
    }

    public function canSell(Item $item, int $price) {
        $buy = $this->getBuy($item);
        if(!isset($buy[$price])) return false;
        $total = 0;
        foreach($buy[$price] as $count) {
            $total += $count;
        }
        return $item->getCount() <= $total;
    }

    public function canBuy(Item $item, int $price) {
        $sell = $this->getSell($item);
        if(!isset($sell[$price])) return false;
        $total = 0;
        foreach($sell[$price] as $count) {
            $total += $count;
        }
        return $item->getCount() <= $total;
    }

    public function getSellableCount(Item $item, int $price) {
        $buy = $this->getBuy($item);
        if(!isset($buy[$price])) return 0;
        $total = 0;
        foreach($buy[$price] as $count) {
            $total += $count;
        }
        if($item->getCount() <= $total) return $item->getCount();
        return $total;
    }

    public function getBuyableCount(Item $item, int $price) {
        $sell = $this->getSell($item);
        if(!isset($sell[$price])) return 0;
        $total = 0;
        foreach($sell[$price] as $count) {
            $total += $count;
        }
        if($item->getCount() <= $total) return $item->getCount();
        return $total;
    }

    public function addSell(Player $player, Item $item, int $price) {
        $sell = $this->getSell($item);
        $amount = $item->getCount();
        if(isset($sell[$price][$player->getName()])) {
            $amount += $sell[$price][$player->getName()];
        }
        $sell[$price][$player->getName()] = $amount;
        $this->items->setNested($item->getId().":".$item->getDamage().".sell", $sell);
    }

    public function addBuy(Player $player, Item $item, int $price) {
        $buy = $this->getBuy($item);
        $amount = $item->getCount();
        if(isset($buy[$price][$player->getName()])) {
            $amount += $buy[$price][$player->getName()];
        }
        $buy[$price][$player->getName()] = $amount;
        $this->items->setNested($item->getId().":".$item->getDamage().".buy", $buy);
    }

    public function onSell(Player $player, Item $item, int $price) {
        $buy = $this->getBuy($item);
        $amount = $item->getCount();
        if(!isset($buy[$price])) return $amount;
        $buyers = [];
        foreach($buy[$price] as $name => $count) {
            if($amount >= $count) {
                $buyers[$name] = $count;
                $amount -= $count;
            } else {
                $buyers[$name] = $count - $amount;
                $amount = 0;
                break;
            }
            if($amount == 0) break;
        }
        foreach($buyers as $name => $count) {
            $buy[$price][$name] -= $count;
            $log = $this->buylog->get($name, []);
            if(!isset($log[$item->getId().":".$item->getDamage()])) {
                $log[$item->getId().":".$item->getDamage()] = [];
            }
            $log[$item->getId().":".$item->getDamage()][] = ["count" => $count, "price" => $price];
            $this->buylog->set($name, $log);
            if($buy[$price][$name] <= 0) {
                unset($buy[$price][$name]);
            }
        }
        if(empty($buy[$price])) {
            unset($buy[$price]);
        }
        $this->items->setNested($item->getId().":".$item->getDamage().".buy", $buy);
        return $amount;
    }

    public function onBuy(Player $player, Item $item, int $price) {
        $sell = $this->getSell($item);
        $amount = $item->getCount();
        if(!isset($sell[$price])) return $amount;
        $sellers = [];
        foreach($sell[$price] as $name => $count) {
            if($amount >= $count) {
                $sellers[$name] = $count;
                $amount -= $count;
            } else {
                $sellers[$name] = $amount;
                $amount = 0;
                break;
            }
            if($amount == 0) break;
        }
        foreach($sellers as $name => $count) {
            $sell[$price][$name] -= $count;
            $log = $this->selllog->get($name, []);
            if(!isset($log[$item->getId().":".$item->getDamage()])) {
                $log[$item->getId().":".$item->getDamage()] = [];
            }
            $log[$item->getId().":".$item->getDamage()][] = ["count" => $count, "price" => $price];
            $this->selllog->set($name, $log);
            if($sell[$price][$name] <= 0) {
                unset($sell[$price][$name]);
            }
        }
        if(empty($sell[$price])) {
            unset($sell[$price]);
        }
        $this->items->setNested($item->getId().":".$item->getDamage().".sell", $sell);
        return $amount;
    }
}# ItemTrade---
name: ItemTrade
main: aieuo\itemtrade\Main
version: 0.2
api: 3.0.0
author: aieuo
commands:
 trade:
  description: ã‚¢ã‚¤ãƒ†ãƒ ã®å–å¼•
  usage: /trade
  permission: true
...
%Gþöü]ý+é–¥\)ç(þØ   GBMB