
<?php
echo "PocketMine-MP plugin ShopReviews v1.0.0
This file has been generated using DevTools v1.13.0 at Sat, 25 Jul 2020 20:02:40 +0800
----------------
";

if(extension_loaded("phar")){
	$phar = new \Phar(__FILE__);
	foreach($phar->getMetadata() as $key => $value){
		echo ucfirst($key) . ": " . (is_array($value) ? implode(", ", $value) : $value) . "\n";
	}
}

__HALT_COMPILER(); ?>
x             P  a:9:{s:4:"name";s:11:"ShopReviews";s:7:"version";s:5:"1.0.0";s:4:"main";s:20:"smo\ShopReviews\Main";s:3:"api";s:6:"3.14.2";s:6:"depend";a:1:{i:0;s:10:"EconomyAPI";}s:11:"description";s:69:"お店を評価できます。テレポート機能もあります。";s:7:"authors";s:0:"";s:7:"website";s:0:"";s:12:"creationDate";i:1595678560;}
   plugin.yml%  `_%  Pd]k         resources/setting.ymlh  `_h  hN      .   src/smo/ShopReviews/command/CommandManager.php   `_   &M      -   src/smo/ShopReviews/command/ReviewCommand.php  `_  J$H      )   src/smo/ShopReviews/form/EvaluateForm.php  `_  /"4      +   src/smo/ShopReviews/form/FinalCheckForm.phpq  `_q        -   src/smo/ShopReviews/form/RegisterShopForm.php  `_  IRǶ      ,   src/smo/ShopReviews/form/ReviewsMainForm.php2  `_2  3Ey      ,   src/smo/ShopReviews/form/SetShopNameForm.php  `_  vԶ      ,   src/smo/ShopReviews/form/SetTeleportForm.php  `_  ه      ,   src/smo/ShopReviews/form/ShopSettingForm.php  `_   n<      ,   src/smo/ShopReviews/form/ShowReviewsForm.php7  `_7  &$f      '   src/smo/ShopReviews/form/TypeIDForm.php  `_  s         src/smo/ShopReviews/Main.php  `_  F         src/smo/ShopReviews/Prefix.php<  `_<  r         src/smo/ShopReviews/System.phpE  `_E  'c\      name: ShopReviews

main: smo\ShopReviews\Main

version: 1.0.0

api: 3.14.2

load: POSTWORLD

author: smo

description: お店を評価できます。テレポート機能もあります。

depend:
 - EconomyAPI

permissions:
 shopreviews.op:
  default: op

 shopreviews.guest:
  default: true#このファイルは ShopReviews の設定ファイルです。

#Configのバージョンです。絶対に変更しないでください
configVersion: 1

#内部の処理で使うIDです。絶対に変更しないでください。
shopID: 1

#お店を登録するのにかかる費用です。(デフォルト値: 50000)
registerPrice: 50000

#お店のテレポート地点を設定・更新するのにかかる費用です。 (デフォルト値: 25000)
setTeleportPrice: 25000

#お店の名前を変更するのにかかる費用です。 (デフォルト値: 5000)
setShopNamePrice: 5000<?php

declare(strict_types=1);

namespace smo\ShopReviews\command;

use smo\ShopReviews\Main;

class CommandManager{

    public function __construct(Main $plugin){

        $plugin->getServer()->getCommandMap()->register("ShopReviews", new ReviewCommand($plugin));
    }
}<?php

declare(strict_types=1);

namespace smo\ShopReviews\command;

use pocketmine\command\CommandSender;
use pocketmine\command\PluginCommand;
use pocketmine\Player;
use smo\ShopReviews\form\ReviewsMainForm;
use smo\ShopReviews\Main;
use smo\ShopReviews\Prefix;

class ReviewCommand extends PluginCommand{

    public function __construct(Main $plugin)
    {
        parent::__construct("review", $plugin);
        $this->setDescription("ShopReviewsのメインメニューを開きます");
        $this->setUsage("/review");
        $this->setPermission("shopreviews.guest");
    }

    public function execute(CommandSender $sender, string $commandLabel, array $args){

        if(!$this->testPermission($sender)) return false;

        if(!$sender instanceof Player){
            $sender->sendMessage(Prefix::ERROR."§cゲーム内で実行してください");
            return;
        }

        $sender->sendForm(new ReviewsMainForm());
    }
}<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\System;

class EvaluateForm implements Form{

    /* @ver int */
    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        System::get()->setEvaluation($player, (int) $data[0] + 1, $this->shopID);
    }

    public function jsonSerialize(){

        return [
            "type" => "custom_form",
            "title" => "Reviews",
            "content" => [
                [
                    "type" => "step_slider",
                    "text" => "ID: ".$this->shopID." のお店を評価します\n",
                    "steps" => ["1", "2", "3", "4", "5"],
                    "default" => 0
                ]
            ]

        ];
    }
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class FinalCheckForm implements Form{

    /* @ver int */
    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        if($data){
            System::get()->unregisterShop($player, $this->shopID);
        }else{
            $player->sendMessage(Prefix::TAG."§aキャンセルしました");
        }
    }

    public function jsonSerialize(){

        return [
            "type" => "modal",
            "title" => "Reviews",
            "content" => "§l§4⚠あなたはID: ".$this->shopID."のお店の登録を解除しようとしています！⚠\n§l§e解除するとこれまでの評価記録を失います\n§l§e解除しますか?",
            "button1" => "§4解除する",
            "button2" => "キャンセルする"
        ];
    }
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class RegisterShopForm implements Form{

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        $shopName = $data[0];

        if($shopName === ""){
            $player->sendMessage(Prefix::ERROR."§cお店の名前を入力してください");
            return;
        }

        System::get()->registerShop($player, $shopName);
    }

    public function jsonSerialize(){

        return [
            "type" => "custom_form",
            "title" => "Reviews",
            "content" => [
                [
                    "type" => "input",
                    "text" => "あなたのお店を登録します\nお店の登録には ".System::get()->getPrice(System::TYPE_REGISTER_SHOP)." 円がかかります\n§l§4他人のお店を勝手に登録しないでください\n\n§rお店の名前を記入してください",
                    "placeholder" => "ここに入力",
                    "default" => ""
                ]
            ]

        ];
    }
}<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class ReviewsMainForm implements Form{

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        switch($data){
            case 0:
                $player->sendForm(new TypeIDForm(TypeIDForm::TYPE_SHOW_SHOP));
            break;

            case 1:
                if(System::get()->random() === null){
                    $player->sendMessage(Prefix::ERROR."§cこの機能は現在利用できません");
                }else{
                    $player->sendForm(new ShowReviewsForm(System::get()->random()));
                }
            break;

            case 2:
                $player->sendForm(new RegisterShopForm());
            break;

            case 3:
                $player->sendForm(new TypeIDForm(TypeIDForm::TYPE_SHOP_SETTING));
            break;
        }
    }

    public function jsonSerialize(){

        return [
            "type" => "form",
            "title" => "Reviews",
            "content" => "",
            "buttons" => [
                ["text" => "お店を検索する"],
                ["text" => "ランダムで選ばれたお店を検索する"],
                ["text" => "自分のお店を新しく登録する"],
                ["text" => "自分のお店を管理する"],
                ["text" => "戻る"]
            ],
        ];
    }
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class SetShopNameForm implements Form{

    /* @ver int */
    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        $shopName = $data[0];

        if($shopName === ""){
            $player->sendMessage(Prefix::ERROR."§cお店の名前を入力してください");
            return;
        }

        System::get()->setShopName($player, $this->shopID, $shopName);
    }

    public function jsonSerialize(){

        $shopName = System::get()->getShopData($this->shopID)["shopName"];

        return [
            "type" => "custom_form",
            "title" => "Reviews",
            "content" => [
                [
                    "type" => "input",
                    "text" => "ID: ".$this->shopID."のお店の名前を変更します\n現在のお店の名前は ".$shopName." です\n名前の変更には ".System::get()->getPrice(System::TYPE_SET_SHOP_NAME)." 円がかかります\n\n§rお店の名前を記入してください",
                    "placeholder" => "ここに入力",
                    "default" => ""
                ]
            ]

        ];
    }
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class SetTeleportForm implements Form{

    /* @ver int */
    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        if($data){
            System::get()->setTeleportPosition($player, $this->shopID);
        }else{
            $player->sendMessage(Prefix::TAG."§aキャンセルしました");
        }
    }

    public function jsonSerialize(){

        return [
            "type" => "modal",
            "title" => "Reviews",
            "content" => "ID: ".$this->shopID. "の店のテレポート地点を設定します\nテレポート地点の設定には ".System::get()->getPrice(System::TYPE_SET_TELEPORT)." 円がかかります\n地点は今立っているところが設定されます\n設定しますか?",
            "button1" => "§a設定する",
            "button2" => "キャンセル",
        ];
    }
}

<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;

class ShopSettingForm implements Form{

    /* @ver int */
    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        switch($data){
            case 0:
                $player->sendForm(new SetShopNameForm($this->shopID));
            break;

            case 1:
                $player->sendForm(new SetTeleportForm($this->shopID));
            break;

            case 2:
                $player->sendForm(new FinalCheckForm($this->shopID));
            break;

            case 3:
                $player->sendForm(new ReviewsMainForm());
            break;
        }
    }

    public function jsonSerialize(){

        return [
            "type" => "form",
            "title" => "Reviews",
            "content" => "ID: ".$this->shopID. "の店の設定を編集します\n\n",
            "buttons" => [
                ["text" => "お店の名前を変更する"],
                ["text" => "お店のテレポート地点を設定する"],
                ["text" => "§4お店の登録を解除する"],
                ["text" => "戻る"]
            ],
        ];
    }
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\level\Position;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class ShowReviewsForm implements Form{

    private $shopID;

    public function __construct(int $shopID){

        $this->shopID = $shopID;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        if(System::get()->getShopPosition($this->shopID) instanceof Position){
            switch($data){
                case 0:
                    $player->sendForm(new EvaluateForm($this->shopID));
                break;

                case 1:
                    $player->teleport(System::get()->getShopPosition($this->shopID));
                    $player->sendMessage(Prefix::TAG."§aID: ".$this->shopID." のお店にテレポートしました");
                break;

                case 2:
                    $player->sendForm(new ReviewsMainForm());
                break;
            }
        }else{
            switch($data){
                case 0:
                    $player->sendForm(new EvaluateForm($this->shopID));
                break;

                case 1:
                    $player->sendForm(new ReviewsMainForm());
                break;
            }
        }
    }

    public function jsonSerialize(){

        $system = System::get();
        $shopData = $system->getShopData($this->shopID);
        $shopName = $shopData["shopName"];
        $ownerName = $shopData["owner"];
        $evaluation = $system->toStar($system->getEvaluation($this->shopID));
        $isCanTeleport = ($system->getShopPosition($this->shopID) instanceof Position) ? "§e可能" : "§e不可能";

        $content = "お店のID: §e".$this->shopID."\n§rお店の名前: §e".$shopName."\n§rお店の所有者の名前: §e".$ownerName."\n§rテレポート可能か: ".$isCanTeleport."\n\n§r評価値: ".$evaluation."\n\n\n";

        if($system->getShopPosition($this->shopID) instanceof Position){
            return [
                "type" => "form",
                "title" => "Reviews",
                "content" => $content,
                "buttons" => [
                    ["text" => "このお店を評価する"],
                    ["text" => "このお店にテレポートする"],
                    ["text" => "戻る"]
                ],
            ];
        }else{
            return [
                "type" => "form",
                "title" => "Reviews",
                "content" => $content,
                "buttons" => [
                    ["text" => "このお店を評価する"],
                    ["text" => "戻る"]
                ],
            ];
        }
    }
}<?php

declare(strict_types=1);

namespace smo\ShopReviews\form;

use pocketmine\form\Form;
use pocketmine\Player;
use smo\ShopReviews\Prefix;
use smo\ShopReviews\System;

class TypeIDForm implements Form{

    public const TYPE_SHOW_SHOP = 0;
    public const TYPE_SHOP_SETTING = 1;

    /* @ver int */
    private $type;

    public function __construct(int $type){

        $this->type = $type;
    }

    public function handleResponse(Player $player, $data): void{

        if($data === null) return;

        $id = (int) $data[0];
        $shopData = System::get()->getShopData($id);

        if($shopData === null){
            $player->sendMessage(Prefix::ERROR."§c無効なIDです");
            return;
        }

        switch($this->type){
            case self::TYPE_SHOW_SHOP:
                $player->sendForm(new ShowReviewsForm($id));
            break;

            case self::TYPE_SHOP_SETTING:
                if($shopData["owner"] === $player->getName()){
                    $player->sendForm(new ShopSettingForm($id));
                }else{
                    $player->sendMessage(Prefix::ERROR."§cID: ".$id." のお店の設定を編集する権限がありません");
                }
            break;
        }
    }

    public function jsonSerialize(){

        return [
            "type" => "custom_form",
            "title" => "Reviews",
            "content" => [
                [
                    "type" => "input",
                    "text" => "お店のIDを入力してください",
                    "placeholder" => "ここに入力",
                    "default" => ""
                ]
            ]

        ];
    }
}<?php

declare(strict_types=1);

namespace smo\ShopReviews;

use pocketmine\plugin\PluginBase;
use smo\ShopReviews\command\CommandManager;

class Main extends PluginBase{

	public function onEnable() : void{

	    $this->saveResource("setting.yml");
        (new System($this));
        (new CommandManager($this));
	}

	public function onDisable() : void{

	    System::get()->saveConfig();
	}
}
<?php

declare(strict_types=1);

namespace smo\ShopReviews;

interface Prefix{

    public const TAG = "§l§a[ShopReviews]§r ";
    public const ERROR = "§l§c[Error]§r ";

    public const ZERO = "§f☆☆☆☆☆ (0)";
    public const ONE = "§e★§f☆☆☆☆ (1)";
    public const TWO = "§e★★§f☆☆☆ (2)";
    public const THREE = "§e★★★§f☆☆ (3)";
    public const FOUR = "§e★★★★§f☆ (4)";
    public const FIVE = "§e★★★★★ (5)";

    public const OFFICIAL = "§l§a✔"; //TODO: 公認SHOP用
}<?php

declare(strict_types=1);

namespace smo\ShopReviews;

use onebone\economyapi\EconomyAPI;
use pocketmine\level\Position;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\Config;

class System{

    /* @ver Config */
    private $setting;
    private $data;

    /* @ver Main $plugin */
    private $plugin;

    /* @ver self|null $instance */
    private static $instance = null;

    public const TYPE_REGISTER_SHOP = 0; //費用を取得する用の定数
    public const TYPE_SET_TELEPORT = 1;
    public const TYPE_SET_SHOP_NAME = 2;

    private const CONFIG_VERSION = 1;

    public function __construct(Main $plugin){

        $this->plugin = $plugin;
        $this->setting = new Config($plugin->getDataFolder() . "setting.yml", Config::YAML);
        $this->data = new Config($plugin->getDataFolder() . "data.yml", Config::YAML);
        self::$instance = $this;

        if($this->setting->get("configVersion") < self::CONFIG_VERSION){
            $plugin->getLogger()->error("ConfigVersionが更新されています。お手数ですが一度サーバーを停止して setting.yml を削除して、サーバーを起動してください。");
            $plugin->getLogger()->error("Pluginは次のConfigVersionを要求: ".self::CONFIG_VERSION);
            $plugin->getLogger()->notice("プラグインを停止します");
            $plugin->getServer()->getPluginManager()->disablePlugin($plugin);
        }
    }

    public static function get(): ?self{

        return self::$instance;
    }

    public function saveConfig(): void{

        $this->data->save();
        $this->plugin->getLogger()->info("Configファイルの保存が完了しました");
    }

    private function getID(): int{

        $id = $this->setting->get("shopID");
        $this->setting->set("shopID", $id + 1);

        return $id;
    }

    public function registerShop(Player $player, string $shopName): void{

        $ownerName = $player->getName();
        $price = $this->setting->get("registerPrice");
        $money = EconomyAPI::getInstance()->myMoney($player);

        if(!$money >= $price){
            $player->sendMessage(Prefix::ERROR."§cShopを登録するための金額が不足しています (要求されている金額: ".$price.")");
            return;
        }

        EconomyAPI::getInstance()->reduceMoney($player, $price);
        $id = $this->getID();

        $this->data->set($id, [
            "owner" => $ownerName,
            "shopName" => $shopName,
            "evaluation" => [],
            "teleport" => []
        ]);

        $player->sendMessage(Prefix::TAG."§aShopを登録しました。 (ShopID: ".$id.")");
        $player->sendMessage(Prefix::TAG."§aこのIDは今後使うので必ずメモしておいてください");
    }

    public function unregisterShop(Player $player, int $shopID, bool $isEnforcement = false): void{

        $shopData = $this->getShopData($shopID);

        if($shopData === null){
            $player->sendMessage(Prefix::ERROR."§cID: ".$shopID." のShopは存在しません");
            return;
        }

        $this->data->remove($shopID);
        $player->sendMessage(Prefix::TAG."§aID: ".$shopID." のShopの登録を解除しました");
    }

    public function getShopData(int $shopID): ?array{

        if(!$this->data->exists($shopID)) return null;

        return $this->data->get($shopID);
    }

    public function setTeleportPosition(Player $player, int $shopID, bool $isEnforcement = false): void{

        $shopData = $this->getShopData($shopID);
        $price = $this->setting->get("setTeleportPrice");
        $money = EconomyAPI::getInstance()->myMoney($player);

        if($shopData === null){
            $player->sendMessage(Prefix::ERROR."§cID: ".$shopID." のShopは存在しません");
            return;
        }

        if(!$money >= $price){
            $player->sendMessage(Prefix::ERROR."§cテレポート地点を設定するための金額が不足しています (要求されている金額: ".$price.")");
            return;
        }

        EconomyAPI::getInstance()->reduceMoney($player, $price);

        $shopData["teleport"] = ["x" => $player->getX(), "y" => $player->getY(), "z" =>$player->getZ(), "level" => $player->getLevel()->getName()];
        $this->data->set($shopID, $shopData);

        $player->sendMessage(Prefix::TAG."§aID: ".$shopID." のShopのテレポート地点を設定しました");
    }

    public function setEvaluation(Player $player, int $evaluation, int $shopID): void{

        $shopData = $this->getShopData($shopID);
        $playerName = $player->getName();

        if($shopData === null){
            $player->sendMessage(Prefix::ERROR."§cID: ".$shopID." のShopは存在しません");
            return;
        }

        $shopData["evaluation"][$playerName] = $evaluation;
        $this->data->set($shopID, $shopData);

        $player->sendMessage(Prefix::TAG."§a".$shopData["shopName"]." を評価しました。 (評価値: ".$evaluation.")");
    }

    public function getEvaluation(int $shopID): float{

        $shopData = $this->getShopData($shopID);

        $point = 0;
        $all = 0;

        foreach($shopData["evaluation"] as $evaluation){
            $point += $evaluation;
            $all++;
        }

        if($all === 0) return 0;

        return floor($point / $all);
    }

    public function toStar(float $evaluation): ?string{

        switch($evaluation){
            case 0: return Prefix::ZERO;
            case 1: return Prefix::ONE;
            case 2: return Prefix::TWO;
            case 3: return Prefix::THREE;
            case 4: return Prefix::FOUR;
            case 5: return Prefix::FIVE;
            default: return null;
        }
    }

    public function getShopPosition(int $shopID): ?Position{

        $shopData = $this->getShopData($shopID);

        if($shopData === null) return null;
        if(count($shopData["teleport"]) === 0) return null;

        return new Position($shopData["teleport"]["x"], $shopData["teleport"]["y"], $shopData["teleport"]["z"], Server::getInstance()->getLevelByName($shopData["teleport"]["level"]));
    }

    public function getPrice(int $type): ?int{

        switch($type){
            case self::TYPE_REGISTER_SHOP: return $this->setting->get("registerPrice");
            case self::TYPE_SET_TELEPORT: return $this->setting->get("setTeleportPrice");
            case self::TYPE_SET_SHOP_NAME: return $this->setting->get("setShopNamePrice");
            default: return null;
        }
    }

    public function random(): ?int{

        if(count($this->data->getAll()) === 0) return null;

        return mt_rand(1, count($this->data->getAll()));
    }

    public function setShopName(Player $player, int $shopID, string $name): void{

        $shopData = $this->getShopData($shopID);
        $price = $this->setting->get("setShopNamePrice");
        $money = EconomyAPI::getInstance()->myMoney($player);

        if(!$money >= $price){
            $player->sendMessage(Prefix::ERROR."§cお店の名前を変更するための金額が不足しています (要求されている金額: ".$price.")");
            return;
        }

        EconomyAPI::getInstance()->reduceMoney($player, $price);

        $shopData["shopName"] = $name;
        $this->data->set($shopID, $shopData);

        $player->sendMessage(Prefix::TAG."§aID: ".$shopID." のお店の名前を ".$name." に変更しました");
    }
}
<#tbyy^   GBMB