diff --git a/EconomyAPI/plugin.yml b/EconomyAPI/plugin.yml index b8235eea..450a7153 100644 --- a/EconomyAPI/plugin.yml +++ b/EconomyAPI/plugin.yml @@ -2,7 +2,7 @@ name: EconomyAPI main: onebone\economyapi\EconomyAPI version: "3.0.0-SNAPSHOT" author: onebone -api: 3.9.0 +api: 5.0.0 permissions: economyapi: diff --git a/EconomyAPI/src/onebone/economyapi/EconomyAPI.php b/EconomyAPI/src/onebone/economyapi/EconomyAPI.php index 16230f68..a5c0ce6c 100644 --- a/EconomyAPI/src/onebone/economyapi/EconomyAPI.php +++ b/EconomyAPI/src/onebone/economyapi/EconomyAPI.php @@ -60,15 +60,14 @@ use pocketmine\command\CommandSender; use pocketmine\event\Listener; use pocketmine\event\player\PlayerJoinEvent; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\PluginBase; use pocketmine\utils\Config; -use pocketmine\utils\Internet; use pocketmine\utils\TextFormat; use Throwable; class EconomyAPI extends PluginBase implements Listener { - const API_VERSION = 4; + const API_VERSION = 5; const PACKAGE_VERSION = "6.0"; /** @@ -119,6 +118,101 @@ class EconomyAPI extends PluginBase implements Listener { private $lang = []; + public function onLoad(): void { + self::$instance = $this; + } + + public function onEnable(): void { + if(!file_exists($this->getDataFolder())) { + mkdir($this->getDataFolder()); + } + + $this->saveDefaultConfig(); + $this->saveResource("lang_en.json"); + + $this->pluginConfig = new PluginConfig($this->getConfig()); + + // Load language files + $this->loadLanguages(); + + // Initialize providers + $this->initializeProviders(); + + // Initialize currencies + $this->initializeCurrencies(); + + // Register events + $this->getServer()->getPluginManager()->registerEvents($this, $this); + $this->getServer()->getPluginManager()->registerEvents(new EventListener($this), $this); + + // Register commands + $this->registerCommands(); + + // Start save task + $this->getScheduler()->scheduleRepeatingTask(new SaveTask($this), $this->pluginConfig->getSaveInterval() * 20); + + $this->getLogger()->info("EconomyAPI has been enabled"); + } + + public function onDisable(): void { + if($this->provider instanceof Provider) { + $this->provider->save(); + $this->provider->close(); + } + } + + private function loadLanguages(): void { + $languages = ["ch", "cs", "de", "en", "fr", "id", "it", "ja", "ko", "nl", "ru", "zh"]; + + foreach($languages as $lang) { + $file = $this->getDataFolder() . "lang_" . $lang . ".json"; + if(file_exists($file)) { + $this->lang[$lang] = json_decode(file_get_contents($file), true); + } + } + } + + private function initializeProviders(): void { + $provider = strtolower($this->pluginConfig->getProvider()); + + switch($provider) { + case "yaml": + $this->provider = new YamlUserProvider($this->getDataFolder() . "user.yml"); + break; + case "mysql": + // MySQL provider initialization + $this->provider = new DummyUserProvider(); // Fallback + break; + default: + $this->provider = new DummyUserProvider(); + break; + } + } + + private function initializeCurrencies(): void { + // Initialize default currency + $defaultCurrency = new CurrencyDollar(); + $this->defaultCurrency = new CurrencyHolder("dollar", $defaultCurrency, null, null, null); + $this->currencies["dollar"] = $this->defaultCurrency; + + // Initialize currency selector + $this->currencySelector = new SimpleCurrencySelector($this); + } + + private function registerCommands(): void { + $commandMap = $this->getServer()->getCommandMap(); + + $commandMap->register("economyapi", new EconomyCommand($this)); + $commandMap->register("economyapi", new GiveMoneyCommand($this)); + $commandMap->register("economyapi", new MyMoneyCommand($this)); + $commandMap->register("economyapi", new MyStatusCommand($this)); + $commandMap->register("economyapi", new PayCommand($this)); + $commandMap->register("economyapi", new SeeMoneyCommand($this)); + $commandMap->register("economyapi", new SetMoneyCommand($this)); + $commandMap->register("economyapi", new TakeMoneyCommand($this)); + $commandMap->register("economyapi", new TopMoneyCommand($this)); + } + /** * Returns instance of EconomyAPI. Should be called after onLoad() phase. * @return EconomyAPI @@ -333,6 +427,70 @@ public function hasCurrency($val): bool { return false; } + /** + * @param string $id + * @return Currency|null + */ + public function getCurrency(string $id): ?Currency { + return isset($this->currencies[$id]) ? $this->currencies[$id]->getCurrency() : null; + } + + /** + * @param Currency $currency + * @return string|null + */ + public function getCurrencyId(Currency $currency): ?string { + foreach($this->currencies as $id => $holder) { + if($holder->getCurrency() === $currency) { + return $id; + } + } + return null; + } + + /** + * @param Currency|null $currency + * @return CurrencyHolder|null + */ + public function getCurrencyHolder(?Currency $currency): ?CurrencyHolder { + if($currency === null) { + return $this->defaultCurrency; + } + + foreach($this->currencies as $holder) { + if($holder->getCurrency() === $currency) { + return $holder; + } + } + return null; + } + + /** + * @param Currency|null $currency + * @param Player|string|null $player + * @return CurrencyHolder + */ + private function findCurrencyHolder(?Currency $currency, $player): CurrencyHolder { + if($currency !== null) { + $holder = $this->getCurrencyHolder($currency); + if($holder !== null) { + return $holder; + } + } + + if($player !== null) { + $preferred = $this->getPlayerPreferredCurrency($player, true); + if($preferred !== null) { + $holder = $this->getCurrencyHolder($preferred); + if($holder !== null) { + return $holder; + } + } + } + + return $this->defaultCurrency; + } + /** * @return array */ @@ -480,7 +638,7 @@ private function canAddMoney($player, float $amount, bool $force, ?Issuer $issue $ev = new AddMoneyEvent($this, $player, $holder->getCurrency(), $amount, $issuer); $ev->call(); - if($ev->setCancelled() and $force === false) { + if($ev->isCancelled() and $force === false) { return self::RET_CANCELLED; } @@ -605,28 +763,23 @@ public function createAccount($player, $currency = null, $defaultMoney = false, $ev = new CreateAccountEvent($this, $player, $holder->getCurrency(), $defaultMoney, $issuer); $ev->call(); + if($ev->isCancelled()) { + return false; + } - $holder->getBalanceRepository()->createAccount($player, $ev->getDefaultMoney()); - return true; + return $holder->getBalanceRepository()->createAccount($player, $defaultMoney); } - return false; } /** - * @experimental - * - * Executes multiple actions at the same time. - * - * Be aware that the function does not guarantee atomicity if actions in $transaction contains actions - * with multiple types of currencies. Also currency availability for a player is not considered during - * the transaction. - * - * @param Transaction $transaction - * @param Issuer|null $issuer - * @return bool Returns true if succeed or false if failed. If actions contain multiple currencies, - * atomicity is not guaranteed. + * @param PlayerJoinEvent $event + * @priority MONITOR + * @ignoreCancelled true */ +<<<<<<< HEAD + public function onPlayerJoin(PlayerJoinEvent $event): void { +======= public function executeTransaction(Transaction $transaction, ?Issuer $issuer = null): bool { $transactionMap = []; foreach($transaction->getActions() as $action) { @@ -913,24 +1066,12 @@ private function registerCommands() { ]); } - public function onJoin(PlayerJoinEvent $event) { + public function onPlayerJoin(PlayerJoinEvent $event) { +>>>>>>> 1011d39ed1ea3ab6f6329818ddb2078ec03b1144 $player = $event->getPlayer(); - - if(!$this->defaultCurrency->getBalanceRepository()->hasAccount($player)) { - $this->getLogger()->debug("UserInfo of '" . $player->getName() . "' is not found. Creating account..."); - $this->createAccount($player, $this->defaultCurrency->getCurrency()); - } - } - - public function onDisable() { - foreach($this->currencies as $currency) { - $currency->close(); - } - } - - public function saveAll() { - foreach($this->currencies as $currency) { - $currency->save(); + + if(!$this->hasAccount($player)) { + $this->createAccount($player); } } -} +} \ No newline at end of file diff --git a/EconomyAPI/src/onebone/economyapi/EventListener.php b/EconomyAPI/src/onebone/economyapi/EventListener.php index 2c84ba33..9428a0be 100644 --- a/EconomyAPI/src/onebone/economyapi/EventListener.php +++ b/EconomyAPI/src/onebone/economyapi/EventListener.php @@ -23,11 +23,14 @@ use pocketmine\event\Listener; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerQuitEvent; +<<<<<<< HEAD +======= use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\types\CommandEnum; -use pocketmine\network\mcpe\protocol\types\CommandParameter; -use pocketmine\Player; +use pocketmine\network\mcpe\protocol\types\command\CommandEnum; +use pocketmine\network\mcpe\protocol\types\command\CommandParameter; +use pocketmine\player\Player; +>>>>>>> 1011d39ed1ea3ab6f6329818ddb2078ec03b1144 class EventListener implements Listener { /** @var EconomyAPI */ @@ -37,142 +40,25 @@ public function __construct(EconomyAPI $plugin) { $this->plugin = $plugin; } - public function onDataPacketSend(DataPacketSendEvent $event) { - $pk = $event->getPacket(); - if(!$pk instanceof AvailableCommandsPacket) return; - - $player = $event->getPlayer(); - - $currencies = self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'currency ID'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = true; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) { - $enum->enumName = 'currencies'; - $enum->enumValues = array_keys($this->plugin->getCurrencies()); - }); - }); - $amount = self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'amount'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_FLOAT; - $it->isOptional = false; - }); - $players = self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'players'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = false; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) { - $enum->enumName = 'players'; - $enum->enumValues = array_map(function(Player $player) { - return $player->getName(); - }, $this->plugin->getServer()->getOnlinePlayers()); - }); - }); - - if(isset($pk->commandData['mymoney'])) { - $data = $pk->commandData['mymoney']; - - $data->overloads = [[$currencies]]; - - $pk->commandData['mymoney'] = $data; - } - - if(isset($pk->commandData['seemoney'])) { - $data = $pk->commandData['seemoney']; - - $data->overloads = [[$players, $currencies]]; - - $pk->commandData['seemoney'] = $data; - } - - foreach(['setmoney', 'givemoney', 'takemoney'] as $command) { - if(isset($pk->commandData[$command])) { - $data = $pk->commandData[$command]; - - $data->overloads = [[$players, $amount, $currencies]]; - - $pk->commandData[$command] = $data; - } - } - - if(isset($pk->commandData['pay'])) { - $data = $pk->commandData['pay']; - - $data->overloads = [ - [ - self::also(new CommandParameter(), function(CommandParameter $it) use ($player) { - $it->paramName = 'target'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = false; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) use ($player) { - $enum->enumName = 'target'; - $enum->enumValues = array_filter(array_map(function(Player $player){ - return $player->getName(); - }, $this->plugin->getServer()->getOnlinePlayers()), function($p) use ($player) { - return $player->getName() !== $p; - }); - }); - }), - $amount, $currencies - ] - ]; - - $pk->commandData['pay'] = $data; - } - - if(isset($pk->commandData['economy'])) { - $data = $pk->commandData['economy']; - - $data->overloads = [ - [ - self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'property'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = false; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) { - $enum->enumName = 'currency'; - $enum->enumValues = ['currency']; - }); - }), - $currencies - ], - [ - self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'property'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = false; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) { - $enum->enumName = 'language'; - $enum->enumValues = ['language']; - }); - }), - self::also(new CommandParameter(), function(CommandParameter $it) { - $it->paramName = 'language'; - $it->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_STRING; - $it->isOptional = false; - $it->enum = self::also(new CommandEnum(), function(CommandEnum $enum) { - $enum->enumName = 'languages'; - $enum->enumValues = $this->plugin->getLanguages(); - }); - }) - ] - ]; - - $pk->commandData['economy'] = $data; - } - } - - /** @noinspection PhpUnusedParameterInspection */ - public function onPlayerJoin(PlayerJoinEvent $_) { + /** + * @param PlayerJoinEvent $event + * @priority MONITOR + * @ignoreCancelled true + */ + public function onPlayerJoin(PlayerJoinEvent $event): void { foreach($this->plugin->getServer()->getOnlinePlayers() as $player) { - $player->sendCommandData(); + $player->getNetworkSession()->syncAvailableCommands(); } } - /** @noinspection PhpUnusedParameterInspection */ - public function onPlayerQuit(PlayerQuitEvent $_) { + /** + * @param PlayerQuitEvent $event + * @priority MONITOR + * @ignoreCancelled true + */ + public function onPlayerQuit(PlayerQuitEvent $event): void { foreach($this->plugin->getServer()->getOnlinePlayers() as $player) { - $player->sendCommandData(); + $player->getNetworkSession()->syncAvailableCommands(); } } @@ -180,4 +66,4 @@ public static function also($object, $block) { $block($object); return $object; } -} +} \ No newline at end of file diff --git a/EconomyAPI/src/onebone/economyapi/command/EconomyCommand.php b/EconomyAPI/src/onebone/economyapi/command/EconomyCommand.php index 893e6cb0..bb764766 100644 --- a/EconomyAPI/src/onebone/economyapi/command/EconomyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/EconomyCommand.php @@ -23,27 +23,27 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\form\CurrencySelectionForm; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class EconomyCommand extends PluginCommand { +class EconomyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("economy"); - parent::__construct("economy", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("economy", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.economy"); } - public function execute(CommandSender $sender, string $commandLabel, array $args): bool { + public function execute(CommandSender $sender, string $commandLabel, array $args): void { if(!$this->testPermission($sender)) { - return false; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; $mode = strtolower(array_shift($args)); $val = array_shift($args); @@ -53,7 +53,7 @@ public function execute(CommandSender $sender, string $commandLabel, array $args case 'language': if(trim($val) === "") { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } if($plugin->setPlayerLanguage($sender->getName(), $val)) { @@ -61,25 +61,22 @@ public function execute(CommandSender $sender, string $commandLabel, array $args }else{ $sender->sendMessage(TextFormat::RED . "There is no language such as $val"); } - return true; + return; case 'currency': - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); - if(trim($val) === '') { if(!$sender instanceof Player) { $sender->sendMessage($plugin->getMessage('economy-currency-specify', $sender)); - return true; + return; } $sender->sendForm(new CurrencySelectionForm($plugin, $plugin->getCurrencies(), $sender)); - return true; + return; } $currency = $plugin->getCurrency($val); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$val])); - return true; + return; } if($plugin->setPlayerPreferredCurrency($sender, $currency)) { @@ -89,12 +86,9 @@ public function execute(CommandSender $sender, string $commandLabel, array $args }else{ $sender->sendMessage($plugin->getMessage('economy-currency-failed', $sender, [$currency->getName()])); } - return true; + return; default: $sender->sendMessage($this->getUsage()); } - - $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return false; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/GiveMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/GiveMoneyCommand.php index 3481b3f3..c8cf35b3 100644 --- a/EconomyAPI/src/onebone/economyapi/command/GiveMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/GiveMoneyCommand.php @@ -23,23 +23,24 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class GiveMoneyCommand extends PluginCommand { +class GiveMoneyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("givemoney"); - parent::__construct("givemoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("givemoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.givemoney"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } $player = array_shift($params); @@ -48,11 +49,10 @@ public function execute(CommandSender $sender, string $label, array $params): bo if(!is_numeric($amount)) { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; if(($p = $plugin->getServer()->getPlayer($player)) instanceof Player) { $player = $p->getName(); @@ -65,7 +65,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo $currency = $plugin->getCurrency($currencyId); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return; } } @@ -95,6 +95,5 @@ public function execute(CommandSender $sender, string $label, array $params): bo break; } - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/MyMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/MyMoneyCommand.php index 8132164b..29d6973f 100644 --- a/EconomyAPI/src/onebone/economyapi/command/MyMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/MyMoneyCommand.php @@ -23,16 +23,17 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class MyMoneyCommand extends PluginCommand { +class MyMoneyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("mymoney"); - parent::__construct("mymoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("mymoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.mymoney"); } @@ -43,8 +44,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo } if($sender instanceof Player) { - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; $currencyId = array_shift($params); if($currencyId !== null) { @@ -52,7 +52,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return false; } }else{ $currency = $plugin->getPlayerPreferredCurrency($sender, false); @@ -76,7 +76,6 @@ public function execute(CommandSender $sender, string $label, array $params): bo return true; } $sender->sendMessage(TextFormat::RED . "Please run this command in-game."); - return true; + return false; } } - diff --git a/EconomyAPI/src/onebone/economyapi/command/MyStatusCommand.php b/EconomyAPI/src/onebone/economyapi/command/MyStatusCommand.php index a63fccc9..6e20e720 100644 --- a/EconomyAPI/src/onebone/economyapi/command/MyStatusCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/MyStatusCommand.php @@ -21,33 +21,33 @@ namespace onebone\economyapi\command; use onebone\economyapi\EconomyAPI; +use pocketmine\command\Command; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class MyStatusCommand extends PluginCommand { +class MyStatusCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("mystatus"); - parent::__construct("mystatus", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("mystatus", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.mystatus"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } if(!$sender instanceof Player) { $sender->sendMessage(TextFormat::RED . "Please run this command in-game."); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; $money = $plugin->getAllMoney(); @@ -61,7 +61,6 @@ public function execute(CommandSender $sender, string $label, array $params): bo } $sender->sendMessage($plugin->getMessage("mystatus-show", $sender, [$topMoney])); - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/PayCommand.php b/EconomyAPI/src/onebone/economyapi/command/PayCommand.php index 609d9243..330bc654 100644 --- a/EconomyAPI/src/onebone/economyapi/command/PayCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/PayCommand.php @@ -24,28 +24,29 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\form\AskPayForm; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class PayCommand extends PluginCommand { +class PayCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("pay"); - parent::__construct("pay", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("pay", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.pay"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } if(!$sender instanceof Player) { $sender->sendMessage(TextFormat::RED . "Please run this command in-game."); - return true; + return; } $player = array_shift($params); @@ -54,11 +55,10 @@ public function execute(CommandSender $sender, string $label, array $params): bo if(!is_numeric($amount)) { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; if($currencyId === null) { $currency = $plugin->getPlayerPreferredCurrency($player, false); @@ -67,14 +67,14 @@ public function execute(CommandSender $sender, string $label, array $params): bo $currency = $plugin->getCurrency($currencyId); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return; } } $money = $plugin->myMoney($sender, $currency); if($money < $amount) { $sender->sendMessage($plugin->getMessage("pay-no-money", $sender, [new CurrencyReplacer($currency, $amount)])); - return true; + return; } if(($p = $plugin->getServer()->getPlayer($player)) instanceof Player) { @@ -83,20 +83,19 @@ public function execute(CommandSender $sender, string $label, array $params): bo if($player === $sender->getName()) { $sender->sendMessage($plugin->getMessage("pay-no-self", $sender)); - return true; + return; } if(!$p instanceof Player and $plugin->getPluginConfig()->getAllowPayOffline() === false) { $sender->sendMessage($plugin->getMessage("player-not-connected", $sender, [$player])); - return true; + return; } if(!$plugin->hasAccount($player, $currency)) { $sender->sendMessage($plugin->getMessage("player-never-connected", $sender, [$player])); - return true; + return; } $sender->sendForm(new AskPayForm($plugin, $sender, $currency, $player, $amount, $label, $params)); - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/SeeMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/SeeMoneyCommand.php index 00d7762a..fa2902d7 100644 --- a/EconomyAPI/src/onebone/economyapi/command/SeeMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/SeeMoneyCommand.php @@ -23,34 +23,34 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class SeeMoneyCommand extends PluginCommand { +class SeeMoneyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("seemoney"); - parent::__construct("seemoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("seemoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.seemoney"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } $player = array_shift($params); $currencyId = array_shift($params); if(trim($player) === "") { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; if(($p = $plugin->getServer()->getPlayer($player)) instanceof Player) { $player = $p->getName(); } @@ -62,7 +62,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo $currency = $plugin->getCurrency($currencyId); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return; } } @@ -72,6 +72,5 @@ public function execute(CommandSender $sender, string $label, array $params): bo }else{ $sender->sendMessage($plugin->getMessage("player-never-connected", $sender, [$player])); } - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/SetMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/SetMoneyCommand.php index b1f54fa6..ae054568 100644 --- a/EconomyAPI/src/onebone/economyapi/command/SetMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/SetMoneyCommand.php @@ -23,23 +23,24 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class SetMoneyCommand extends PluginCommand { +class SetMoneyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("setmoney"); - parent::__construct("setmoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("setmoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.setmoney"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } $player = array_shift($params); @@ -48,11 +49,10 @@ public function execute(CommandSender $sender, string $label, array $params): bo if(!is_numeric($amount)) { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; if(($p = $plugin->getServer()->getPlayer($player)) instanceof Player) { $player = $p->getName(); } @@ -64,7 +64,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo $currency = $plugin->getCurrency($currencyId); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return; } } @@ -76,7 +76,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo ])); }else{ $sender->sendMessage($plugin->getMessage("player-never-connected", $sender, [$player])); - return true; + return; } } @@ -107,6 +107,5 @@ public function execute(CommandSender $sender, string $label, array $params): bo default: $sender->sendMessage("WTF"); } - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/TakeMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/TakeMoneyCommand.php index 7590175e..832ad135 100644 --- a/EconomyAPI/src/onebone/economyapi/command/TakeMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/TakeMoneyCommand.php @@ -23,23 +23,24 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; -use pocketmine\Player; +use pocketmine\command\Command; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class TakeMoneyCommand extends PluginCommand { +class TakeMoneyCommand extends Command { + private EconomyAPI $plugin; + public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("takemoney"); - parent::__construct("takemoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("takemoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.takemoney"); } - public function execute(CommandSender $sender, string $label, array $params): bool { + public function execute(CommandSender $sender, string $label, array $params): void { if(!$this->testPermission($sender)) { - return false; + return; } $player = array_shift($params); @@ -48,18 +49,17 @@ public function execute(CommandSender $sender, string $label, array $params): bo if(!is_numeric($amount)) { $sender->sendMessage(TextFormat::RED . "Usage: " . $this->getUsage()); - return true; + return; } - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; if(($p = $plugin->getServer()->getPlayer($player)) instanceof Player) { $player = $p->getName(); } if($amount < 0) { $sender->sendMessage($plugin->getMessage("takemoney-invalid-number", $sender, [$amount])); - return true; + return; } if($currencyId === null) { @@ -69,7 +69,7 @@ public function execute(CommandSender $sender, string $label, array $params): bo $currency = $plugin->getCurrency($currencyId); if($currency === null) { $sender->sendMessage($plugin->getMessage('currency-unavailable', $sender, [$currencyId])); - return true; + return; } } @@ -103,7 +103,6 @@ public function execute(CommandSender $sender, string $label, array $params): bo break; } - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/command/TopMoneyCommand.php b/EconomyAPI/src/onebone/economyapi/command/TopMoneyCommand.php index 75581e8d..466d6b81 100644 --- a/EconomyAPI/src/onebone/economyapi/command/TopMoneyCommand.php +++ b/EconomyAPI/src/onebone/economyapi/command/TopMoneyCommand.php @@ -23,25 +23,26 @@ use onebone\economyapi\EconomyAPI; use onebone\economyapi\currency\CurrencyReplacer; use pocketmine\command\CommandSender; -use pocketmine\command\PluginCommand; +use pocketmine\command\Command; +use pocketmine\player\Player; + +class TopMoneyCommand extends Command { + private EconomyAPI $plugin; -class TopMoneyCommand extends PluginCommand { public function __construct(EconomyAPI $plugin) { + $this->plugin = $plugin; $desc = $plugin->getCommandMessage("topmoney"); - parent::__construct("topmoney", $plugin); - $this->setDescription($desc["description"]); - $this->setUsage($desc["usage"]); + parent::__construct("topmoney", $desc["description"], $desc["usage"]); $this->setPermission("economyapi.command.topmoney"); } - public function execute(CommandSender $sender, string $label, array $params): bool { - if(!$this->testPermission($sender)) return false; + public function execute(CommandSender $sender, string $label, array $params): void { + if(!$this->testPermission($sender)) return; $page = max(1, (int) array_shift($params)); - /** @var EconomyAPI $plugin */ - $plugin = $this->getPlugin(); + $plugin = $this->plugin; $currency = $plugin->getPlayerPreferredCurrency($sender, false); @@ -58,6 +59,5 @@ public function execute(CommandSender $sender, string $label, array $params): bo })->catch(function() use ($sender) { $sender->sendMessage('Failed to fetch money leaderboard :('); }); - return true; } } diff --git a/EconomyAPI/src/onebone/economyapi/event/CommandIssuer.php b/EconomyAPI/src/onebone/economyapi/event/CommandIssuer.php index bea40e28..ca096015 100644 --- a/EconomyAPI/src/onebone/economyapi/event/CommandIssuer.php +++ b/EconomyAPI/src/onebone/economyapi/event/CommandIssuer.php @@ -20,7 +20,7 @@ namespace onebone\economyapi\event; -use pocketmine\Player; +use pocketmine\player\Player; class CommandIssuer implements Issuer { /** @var Player */ @@ -51,4 +51,4 @@ public function getLine(): string { public function __toString(): string { return "Command({$this->line}) from player {$this->player->getName()}"; } -} +} \ No newline at end of file diff --git a/EconomyAPI/src/onebone/economyapi/internal/BalanceRepository.php b/EconomyAPI/src/onebone/economyapi/internal/BalanceRepository.php index 4bcf6453..447badc3 100644 --- a/EconomyAPI/src/onebone/economyapi/internal/BalanceRepository.php +++ b/EconomyAPI/src/onebone/economyapi/internal/BalanceRepository.php @@ -28,7 +28,7 @@ use onebone\economyapi\util\Transaction; use onebone\economyapi\util\TransactionAction; use onebone\economyapi\util\TransactionResult; -use pocketmine\Player; +use pocketmine\player\Player; /** * @internal @@ -37,125 +37,76 @@ * THIS IS INTERNAL CLASS, AND IS SUBJECT TO CHANGE ANYTIME WITHOUT NOTICE. */ class BalanceRepository { - /** @var Currency */ - private $currency; /** @var Provider */ private $provider; + /** @var Currency */ + private $currency; /** @var ReversionProvider */ private $reversionProvider; - public function __construct(Currency $currency, Provider $provider, ReversionProvider $reversionProvider) { - $this->currency = $currency; + public function __construct(Provider $provider, Currency $currency, ReversionProvider $reversionProvider) { $this->provider = $provider; + $this->currency = $currency; $this->reversionProvider = $reversionProvider; } - public function tryFlushPending() { - $pending = $this->reversionProvider->getAllPending(); - if($this->provider->executeTransaction( - $this->revertActionToTransactionAction($pending) - )) { - $this->reversionProvider->clearPending(); - } - } - - /** - * @param RevertAction[] $reverts - * @return TransactionAction[] - */ - private function revertActionToTransactionAction(array $reverts): array { - $actions = []; - foreach($reverts as $entry) { - if($entry->getType() === RevertAction::ADD) { - $type = Transaction::ACTION_ADD; - }else{ - $type = Transaction::ACTION_REDUCE; - } - - $actions[] = new TransactionAction($type, $entry->getPlayer(), $entry->getValue(), $this->currency); - } - - return $actions; - } - - public function getAllBalances(): array { - return $this->provider->getAll(); - } - /** * @param string|Player $player * @return bool */ public function hasAccount($player): bool { - return $this->provider->hasAccount($player); + if($player instanceof Player) { + $player = $player->getName(); + } + $player = strtolower($player); + + return $this->provider->accountExists($player); } /** * @param string|Player $player - * @param float $defaultBalance + * @param float $defaultMoney * @return bool */ - public function createAccount($player, float $defaultBalance): bool { - return $this->provider->createAccount($player, $defaultBalance); - } + public function createAccount($player, float $defaultMoney = 1000): bool { + if($player instanceof Player) { + $player = $player->getName(); + } + $player = strtolower($player); - public function sortByRange(int $from, ?int $len): Promise { - return $this->provider->sortByRange($from, $len); + return $this->provider->createAccount($player, $defaultMoney); } /** * @param string|Player $player - * @return bool|float + * @return float */ - public function getMoney($player) { - $balance = $this->provider->getMoney($player); - if($balance === false) return $balance; - + public function getMoney($player): float { if($player instanceof Player) { $player = $player->getName(); } $player = strtolower($player); - return $balance + $this->reversionProvider->getPendingBalance($player); - } - - /** - * @param TransactionAction[] $actions - * @return TransactionResult - */ - public function executeTransaction(array $actions): TransactionResult { - // TODO merge with pending transaction? - return $this->provider->executeTransaction($actions); - } - - /** - * @param RevertAction[] $actions - */ - public function revert(array $actions) { - $this->reversionProvider->addRevertActions($actions); + return $this->provider->getMoney($player); } /** * @param string|Player $player - * @param float $value - * @param TransactionAction|null $action Action to be used to revert the operation - * - * @return int Result code - * + * @param float $amount + * @param RevertAction|null $revertAction + * @return int */ - public function addMoney($player, float $value, ?TransactionAction &$action): int { - // TODO provider should check constraints such as limiting balance going over maximum value by itself + public function setMoney($player, float $amount, ?RevertAction &$revertAction = null): int { + if($player instanceof Player) { + $player = $player->getName(); + } + $player = strtolower($player); - $result = $this->provider->addMoney($player, $value); + $oldMoney = $this->provider->getMoney($player); + $result = $this->provider->setMoney($player, $amount); + if($result === EconomyAPI::RET_SUCCESS) { - $action = new TransactionAction(Transaction::ACTION_REDUCE, $player, $value, $this->currency); - }else{ - $action = null; + $revertAction = new RevertAction(RevertAction::ADD, $player, $oldMoney - $amount); } return $result; @@ -163,25 +114,20 @@ public function addMoney($player, float $value, ?TransactionAction &$action): in /** * @param string|Player $player - * @param float $value - * @param TransactionAction|null $action Action to be used to revert the operation - * - * @return int Result code - * + * @param float $amount + * @param RevertAction|null $revertAction + * @return int */ - public function reduceMoney($player, float $value, ?TransactionAction &$action): int { - // TODO provider should check constraints such as limiting balance going to negative value by itself + public function addMoney($player, float $amount, ?RevertAction &$revertAction = null): int { + if($player instanceof Player) { + $player = $player->getName(); + } + $player = strtolower($player); - $result = $this->provider->reduceMoney($player, $value); + $result = $this->provider->addMoney($player, $amount); + if($result === EconomyAPI::RET_SUCCESS) { - $action = new TransactionAction(Transaction::ACTION_ADD, $player, $value, $this->currency); - }else{ - $action = null; + $revertAction = new RevertAction(RevertAction::REDUCE, $player, $amount); } return $result; @@ -189,42 +135,42 @@ public function reduceMoney($player, float $value, ?TransactionAction &$action): /** * @param string|Player $player - * @param float $value - * @param TransactionAction|null $action Action to be used to revert the operation - * - * @return int Result code or old balance - * + * @param float $amount + * @param RevertAction|null $revertAction + * @return int */ - public function setMoney($player, float $value, ?TransactionAction &$action): int { - // TODO provider should check constraints such as limiting balance going over maximum value or to negative value by itself - - $result = $this->provider->setMoney($player, $value); - - $action = null; - if($result >= 0) { // operation has succeed and provider returned old balance value - $delta = $value - $result; - if($delta < 0) { - $action = new TransactionAction(Transaction::ACTION_ADD, $player, $delta, $this->currency); - }else if($delta > 0) { - $action = new TransactionAction(Transaction::ACTION_REDUCE, $player, $delta, $this->currency); - } + public function reduceMoney($player, float $amount, ?RevertAction &$revertAction = null): int { + if($player instanceof Player) { + $player = $player->getName(); + } + $player = strtolower($player); + + $result = $this->provider->reduceMoney($player, $amount); + + if($result === EconomyAPI::RET_SUCCESS) { + $revertAction = new RevertAction(RevertAction::ADD, $player, $amount); } return $result; } - public function close() { - $this->provider->close(); - $this->reversionProvider->close(); + /** + * @return array + */ + public function getAllBalances(): array { + return $this->provider->getAll(); } - public function save() { - $this->provider->save(); - $this->reversionProvider->save(); + /** + * @param int $page + * @param int $entriesPerPage + * @return array + */ + public function getTopBalances(int $page = 1, int $entriesPerPage = 10): array { + $all = $this->provider->getAll(); + arsort($all); + + $offset = ($page - 1) * $entriesPerPage; + return array_slice($all, $offset, $entriesPerPage, true); } -} +} \ No newline at end of file diff --git a/EconomyAPI/src/onebone/economyapi/provider/YamlProvider.php b/EconomyAPI/src/onebone/economyapi/provider/YamlProvider.php index f8829df7..f2e9e836 100644 --- a/EconomyAPI/src/onebone/economyapi/provider/YamlProvider.php +++ b/EconomyAPI/src/onebone/economyapi/provider/YamlProvider.php @@ -27,7 +27,7 @@ use onebone\economyapi\util\Transaction; use onebone\economyapi\util\TransactionAction; use onebone\economyapi\util\TransactionResult; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Config; class YamlProvider implements Provider { diff --git a/EconomyAPI/src/onebone/economyapi/task/SaveTask.php b/EconomyAPI/src/onebone/economyapi/task/SaveTask.php index b5fa6d02..a79f7427 100644 --- a/EconomyAPI/src/onebone/economyapi/task/SaveTask.php +++ b/EconomyAPI/src/onebone/economyapi/task/SaveTask.php @@ -25,13 +25,13 @@ class SaveTask extends Task { /** @var EconomyAPI */ - protected $plugin; + private EconomyAPI $plugin; public function __construct(EconomyAPI $plugin) { $this->plugin = $plugin; } - public function onRun(int $currentTick) { + public function onRun(): void { $this->plugin->saveAll(); } } diff --git a/EconomyAirport/plugin.yml b/EconomyAirport/plugin.yml index d9922bdc..e1c71dc3 100644 --- a/EconomyAirport/plugin.yml +++ b/EconomyAirport/plugin.yml @@ -1,16 +1,31 @@ name: EconomyAirport +<<<<<<< HEAD +======= version: "2.0.4" author: onebone -api: 3.9.0 +api: 5.0.0 +>>>>>>> 1011d39ed1ea3ab6f6329818ddb2078ec03b1144 main: onebone\economyairport\EconomyAirport +version: "2.0.0" +author: onebone +api: 5.0.0 depend: [EconomyAPI] +commands: + airport: + description: "Airport teleportation command" + usage: "/airport [add|remove|list|]" + permission: economyairport.command + permissions: - economyairport: - description: Includes all permissions related to EconomyAirport - children: - economyairport.create: - description: Allows player construction of airport - economyairport.remove: - description: Allows player to remove airport + economyairport: + default: op + description: "Allows access to all EconomyAirport features" + children: + economyairport.command: + default: true + description: "Allows use of airport command" + economyairport.admin: + default: op + description: "Allows adding and removing airports" \ No newline at end of file diff --git a/EconomyAirport/src/onebone/economyairport/EconomyAirport.php b/EconomyAirport/src/onebone/economyairport/EconomyAirport.php index 3f3923e4..02d647fd 100644 --- a/EconomyAirport/src/onebone/economyairport/EconomyAirport.php +++ b/EconomyAirport/src/onebone/economyairport/EconomyAirport.php @@ -21,197 +21,214 @@ namespace onebone\economyairport; use onebone\economyapi\EconomyAPI; -use pocketmine\event\block\BlockBreakEvent; -use pocketmine\event\block\SignChangeEvent; +use pocketmine\command\Command; +use pocketmine\command\CommandSender; use pocketmine\event\Listener; -use pocketmine\event\player\PlayerInteractEvent; -use pocketmine\level\Level; -use pocketmine\level\Position; -use pocketmine\math\Vector3; +use pocketmine\player\Player; use pocketmine\plugin\PluginBase; -use pocketmine\tile\Sign; use pocketmine\utils\Config; +use pocketmine\utils\TextFormat; +use pocketmine\world\Position; class EconomyAirport extends PluginBase implements Listener { - private $airport; - - /** - * @var Config - */ - private $lang, $tag; - - public function onEnable() { + /** @var EconomyAPI */ + private $api; + /** @var Config */ + private $airports; + /** @var Config */ + private $lang; + + public function onEnable(): void { if(!file_exists($this->getDataFolder())) { mkdir($this->getDataFolder()); } - $this->airport = array(); + $this->api = EconomyAPI::getInstance(); + if($this->api === null) { + $this->getLogger()->critical("EconomyAPI plugin not found!"); + $this->getServer()->getPluginManager()->disablePlugin($this); + return; + } - $this->saveResource("language.properties"); + $this->saveDefaultConfig(); $this->saveResource("airport.yml"); - $this->lang = new Config($this->getDataFolder() . "language.properties", Config::PROPERTIES); - $this->tag = new Config($this->getDataFolder() . "airport.yml", Config::YAML); + $this->saveResource("language.properties"); - $airportYml = new Config($this->getDataFolder() . "AirportData.yml", Config::YAML); - $this->airport = $airportYml->getAll(); + $this->airports = new Config($this->getDataFolder() . "airport.yml", Config::YAML); + $this->lang = new Config($this->getDataFolder() . "language.properties", Config::PROPERTIES); $this->getServer()->getPluginManager()->registerEvents($this, $this); - } - public function onDisable() { - $airportYml = new Config($this->getDataFolder() . "AirportData.yml", Config::YAML); - $airportYml->setAll($this->airport); - $airportYml->save(); + $this->getLogger()->info("EconomyAirport has been enabled"); } - public function onSignChange(SignChangeEvent $event) { - if(($data = $this->checkTag($event->getLine(0), $event->getLine(1))) !== false) { - $player = $event->getPlayer(); - if(!$player->hasPermission("economyairport.create")) { - $player->sendMessage($this->getMessage("no-permission-create")); - return; + public function onCommand(CommandSender $sender, Command $command, string $label, array $args): bool { + if($command->getName() === "airport") { + if(!$sender instanceof Player) { + $sender->sendMessage(TextFormat::RED . "Please run this command in-game."); + return true; } - $block = $event->getBlock(); - switch ($event->getLine(1)) { - case "departure": - if(!is_numeric($event->getLine(2))) { - $player->sendMessage($this->getMessage("cost-must-be-numeric")); - break; - } - if(trim($event->getLine(3)) === "") { - $player->sendMessage($this->getMessage("no-target-airport")); - break; + + if(!isset($args[0])) { + $this->showAirportList($sender); + return true; + } + + $subCommand = strtolower($args[0]); + + switch($subCommand) { + case "add": + if(!$sender->hasPermission("economyairport.admin")) { + $sender->sendMessage(TextFormat::RED . "You don't have permission to add airports."); + return true; } - foreach($this->airport as $d) { - if($d["type"] === 1 and $d["name"] === $event->getLine(3)) { - $targetX = $d[0]; - $targetY = $d[1]; - $targetZ = $d[2]; - $targetLevel = $d[3]; - break; - } + if(!isset($args[1]) || !isset($args[2])) { + $sender->sendMessage(TextFormat::RED . "Usage: /airport add "); + return true; } - if(!isset($targetX)) { - $player->sendMessage($this->getMessage("no-arrival")); - break; + + $name = $args[1]; + $price = (float) $args[2]; + + if($price < 0) { + $sender->sendMessage(TextFormat::RED . "Price cannot be negative."); + return true; } - $this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()] = array( - "type" => 0, - "cost" => ($cost = round($event->getLine(2))), - "target" => $event->getLine(3), - "targetX" => $targetX, - "targetY" => $targetY, - "targetZ" => $targetZ, - "targetLevel" => $targetLevel - ); - $mu = EconomyAPI::getInstance()->getMonetaryUnit(); - $event->setLine(0, str_replace("%MONETARY_UNIT%", $mu, $data[0])); - $event->setLine(1, str_replace("%MONETARY_UNIT%", $mu, $data[1])); - $event->setLine(2, str_replace(["%1", "%MONETARY_UNIT%"], [$cost, $mu], $data[2])); - $event->setLine(3, str_replace(["%2", "%MONETARY_UNIT%"], [$event->getLine(3)], $data[3])); - - $player->sendMessage($this->getMessage("departure-created", [$event->getLine(3), $cost])); + + $this->addAirport($sender, $name, $price); break; - case "arrival": - if(trim($event->getLine(2)) === "") { - $player->sendMessage($this->getMessage("no-airport-name")); - break; + + case "remove": + if(!$sender->hasPermission("economyairport.admin")) { + $sender->sendMessage(TextFormat::RED . "You don't have permission to remove airports."); + return true; } - if(strpos($event->getLine(2), ":")) { - $player->sendMessage($this->getMessage("invalid-airport-name")); - break; + + if(!isset($args[1])) { + $sender->sendMessage(TextFormat::RED . "Usage: /airport remove "); + return true; } - $this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()] = array( - $block->getX(), $block->getY(), $block->getZ(), $block->getLevel()->getFolderName(), - "name" => $event->getLine(2), - "type" => 1 - ); - - $player->sendMessage($this->getMessage("arrival-created", [$event->getLine(2), "%2"])); - - $event->setLine(0, $data[0]); - $event->setLine(1, $data[1]); - $event->setLine(2, str_replace("%1", $event->getLine(2), $data[2])); - $event->setLine(3, ""); + + $name = $args[1]; + $this->removeAirport($sender, $name); + break; + + case "list": + $this->showAirportList($sender); + break; + + default: + // Try to teleport to airport + $airportName = $args[0]; + $this->teleportToAirport($sender, $airportName); break; } + + return true; } + + return false; } - public function checkTag($firstLine, $secondLine) { - if(!$this->tag->exists($secondLine)) { - return false; - } - foreach($this->tag->get($secondLine) as $key => $data) { - if($firstLine === $key) { - return $data; - } + private function addAirport(Player $player, string $name, float $price): void { + $airports = $this->airports->getAll(); + + if(isset($airports[$name])) { + $player->sendMessage(TextFormat::RED . $this->getMessage("airport-exists", [$name])); + return; } - return false; + + $pos = $player->getPosition(); + $airports[$name] = [ + "x" => $pos->getFloorX(), + "y" => $pos->getFloorY(), + "z" => $pos->getFloorZ(), + "world" => $pos->getWorld()->getFolderName(), + "price" => $price + ]; + + $this->airports->setAll($airports); + $this->airports->save(); + + $player->sendMessage(TextFormat::GREEN . $this->getMessage("airport-added", [$name, $price])); } - public function getMessage($key, $value = ["%1", "%2"]) { - if($this->lang->exists($key)) { - return str_replace(["%1", "%2"], [$value[0], $value[1]], $this->lang->get($key)); - }else{ - return "Language with key \"$key\" does not exist"; + private function removeAirport(Player $player, string $name): void { + $airports = $this->airports->getAll(); + + if(!isset($airports[$name])) { + $player->sendMessage(TextFormat::RED . $this->getMessage("airport-not-exists", [$name])); + return; } + + unset($airports[$name]); + $this->airports->setAll($airports); + $this->airports->save(); + + $player->sendMessage(TextFormat::GREEN . $this->getMessage("airport-removed", [$name])); } - public function onBlockTouch(PlayerInteractEvent $event) { - if($event->getAction() !== PlayerInteractEvent::RIGHT_CLICK_BLOCK) { + private function showAirportList(Player $player): void { + $airports = $this->airports->getAll(); + + if(empty($airports)) { + $player->sendMessage(TextFormat::YELLOW . $this->getMessage("no-airports")); return; } - $block = $event->getBlock(); - if(isset($this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()])) { - $airport = $this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()]; - if($airport["type"] === 1) - return; - $player = $event->getPlayer(); - if(isset($this->airport[$airport["targetX"] . ":" . $airport["targetY"] . ":" . $airport["targetZ"] . ":" . $airport["targetLevel"]]) and $this->airport[$airport["targetX"] . ":" . $airport["targetY"] . ":" . $airport["targetZ"] . ":" . $airport["targetLevel"]]["type"] === 1) { - $money = EconomyAPI::getInstance()->myMoney($player); - if(!$block->getLevel()->getTile(new Vector3($airport["targetX"], $airport["targetY"], $airport["targetZ"])) instanceof Sign) { - $player->sendMessage($this->getMessage("no-airport", [$airport["target"], "%2"])); - unset($this->airport[$airport["target"]]); - return; - } - if($money < $airport["cost"]) { - $player->sendMessage($this->getMessage("no-money", [$airport["cost"], $money])); - }else{ - EconomyAPI::getInstance()->reduceMoney($player, $airport["cost"], true, "EconomyAirport"); - $level = $this->getServer()->getLevelByName($airport["targetLevel"]); - $player->teleport(new Position($airport["targetX"], $airport["targetY"], $airport["targetZ"], $level)); - $time = $level->getTime(); - $day = (int) ($time / Level::TIME_FULL); - $time -= ($day * Level::TIME_FULL); - $phrase = "sunrise"; - if($time < 1200) { - $phrase = "day"; - } elseif($time % Level::TIME_SUNSET < 2000) { - $phrase = "sunset"; - } elseif($time % Level::TIME_NIGHT < 9000) { - $phrase = "night"; - } - $player->sendMessage($this->getMessage("thank-you", [$airport["target"], $level->getTime() . " (" . $phrase . ")"])); - } - }else{ - $player->sendMessage($this->getMessage("no-airport", [$airport["target"], "%2"])); - } + $player->sendMessage(TextFormat::GREEN . $this->getMessage("airport-list-header")); + + foreach($airports as $name => $data) { + $price = $data["price"]; + $world = $data["world"]; + $player->sendMessage(TextFormat::AQUA . "- " . $name . TextFormat::WHITE . " (" . $world . ") - " . TextFormat::GOLD . "$" . $price); } } - public function onBlockBreak(BlockBreakEvent $event) { - $block = $event->getBlock(); - if(isset($this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()])) { - $player = $event->getPlayer(); - if(!$player->hasPermission("economyairport.remove")) { - $player->sendMessage($this->getMessage("no-permission-break")); + private function teleportToAirport(Player $player, string $airportName): void { + $airports = $this->airports->getAll(); + + if(!isset($airports[$airportName])) { + $player->sendMessage(TextFormat::RED . $this->getMessage("airport-not-exists", [$airportName])); + return; + } + + $airport = $airports[$airportName]; + $price = $airport["price"]; + + if($this->api->myMoney($player) < $price) { + $player->sendMessage(TextFormat::RED . $this->getMessage("not-enough-money", [$price])); + return; + } + + $world = $this->getServer()->getWorldManager()->getWorldByName($airport["world"]); + if($world === null) { + $player->sendMessage(TextFormat::RED . $this->getMessage("world-not-found", [$airport["world"]])); + return; + } + + $pos = new Position($airport["x"], $airport["y"], $airport["z"], $world); + + if($price > 0) { + $result = $this->api->reduceMoney($player, $price); + if($result !== EconomyAPI::RET_SUCCESS) { + $player->sendMessage(TextFormat::RED . $this->getMessage("transaction-failed")); return; } - unset($this->airport[$block->getX() . ":" . $block->getY() . ":" . $block->getZ() . ":" . $block->getLevel()->getFolderName()]); - $player->sendMessage($this->getMessage("airport-removed")); } + + $player->teleport($pos); + $player->sendMessage(TextFormat::GREEN . $this->getMessage("teleported-to-airport", [$airportName, $price])); + } + + private function getMessage(string $key, array $params = []): string { + $message = $this->lang->get($key, $key); + + foreach($params as $i => $param) { + $message = str_replace("{%" . ($i + 1) . "}", $param, $message); + } + + return $message; } -} +} \ No newline at end of file diff --git a/EconomyAuction/plugin.yml b/EconomyAuction/plugin.yml index 26c90b26..87caa350 100644 --- a/EconomyAuction/plugin.yml +++ b/EconomyAuction/plugin.yml @@ -1,45 +1,36 @@ name: EconomyAuction main: onebone\economyauction\EconomyAuction +<<<<<<< HEAD +version: "2.0.0" +======= version: "2.0.2" -api: 3.9.0 +api: 5.0.0 +>>>>>>> 1011d39ed1ea3ab6f6329818ddb2078ec03b1144 author: onebone +api: 5.0.0 depend: [EconomyAPI] commands: - auction: - description: Manages all auctions - usage: /auction - permission: economyauction.command.auction + auction: + description: "Auction management command" + usage: "/auction " + permission: economyauction.command permissions: - economyauction: - description: Allows player to use all functions in EconomyAuction - default: op - children: - economyauction.command: - description: Allows player to use all of commands in EconomyAuction + economyauction: default: op + description: "Allows access to all EconomyAuction features" children: - economyauction.command.auction: - description: Allows player to manage all the auctions - default: true - children: - economyauction.command.auction.start: - description: Allows player to start auction with no limited time + economyauction.command: default: true - economyauction.command.auction.stop: - description: Allows player to stop auction by force + description: "Allows use of auction command" + economyauction.start: default: true - economyauction.command.auction.time: - description: Allows player to start auction with limited time + description: "Allows starting auctions" + economyauction.bid: default: true - economyauction.command.auction.bid: - description: Allows player to bid price for an auction - default: true - economyauction.command.auction.list: - description: Allows player to see list of auctions - default: true - economyauction.auction.stop.others: - description: Allows player to stop others' auctions - default: op + description: "Allows bidding on auctions" + economyauction.admin: + default: op + description: "Allows ending auctions forcefully" \ No newline at end of file diff --git a/EconomyAuction/src/onebone/economyauction/EconomyAuction.php b/EconomyAuction/src/onebone/economyauction/EconomyAuction.php index 8b0886bf..4d3a0cfe 100644 --- a/EconomyAuction/src/onebone/economyauction/EconomyAuction.php +++ b/EconomyAuction/src/onebone/economyauction/EconomyAuction.php @@ -23,246 +23,279 @@ use onebone\economyapi\EconomyAPI; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\event\Listener; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\PluginBase; +use pocketmine\utils\Config; use pocketmine\utils\TextFormat; -class EconomyAuction extends PluginBase { - /* - @var int[] $auctions - key : player name - [0] : item - [1] : meta - [2] : count - [3] : start price - [4] : buying player - [5] : buying price - [6] : remain time - [7] : start time - [8] : schedule id - */ - private $auctions, $queue; - - public function onEnable() { +class EconomyAuction extends PluginBase implements Listener { + /** @var EconomyAPI */ + private $api; + /** @var array */ + private $auctions = []; + /** @var Config */ + private $config; + + public function onEnable(): void { if(!file_exists($this->getDataFolder())) { mkdir($this->getDataFolder()); } + + $this->api = EconomyAPI::getInstance(); + if($this->api === null) { + $this->getLogger()->critical("EconomyAPI plugin not found!"); + $this->getServer()->getPluginManager()->disablePlugin($this); + return; + } + $this->saveDefaultConfig(); - if(!is_file($this->getDataFolder() . "Auctions.dat")) { - file_put_contents($this->getDataFolder() . "Auctions.dat", serialize(array())); + $this->saveResource("config.yml"); + + $this->config = $this->getConfig(); + + $this->getServer()->getPluginManager()->registerEvents($this, $this); + + $this->getLogger()->info("EconomyAuction has been enabled"); + } + + public function onCommand(CommandSender $sender, Command $command, string $label, array $args): bool { + if($command->getName() === "auction") { + if(!$sender instanceof Player) { + $sender->sendMessage(TextFormat::RED . "Please run this command in-game."); + return true; + } + + if(!isset($args[0])) { + $sender->sendMessage(TextFormat::RED . "Usage: /auction "); + return true; + } + + $subCommand = strtolower($args[0]); + + switch($subCommand) { + case "start": + if(!$sender->hasPermission("economyauction.start")) { + $sender->sendMessage(TextFormat::RED . "You don't have permission to start auctions."); + return true; + } + + if(!isset($args[1]) || !isset($args[2])) { + $sender->sendMessage(TextFormat::RED . "Usage: /auction start "); + return true; + } + + $startingPrice = (float) $args[1]; + $duration = (int) $args[2]; + + if($startingPrice <= 0) { + $sender->sendMessage(TextFormat::RED . "Starting price must be positive."); + return true; + } + + if($duration <= 0 || $duration > 60) { + $sender->sendMessage(TextFormat::RED . "Duration must be between 1 and 60 minutes."); + return true; + } + + $this->startAuction($sender, $startingPrice, $duration); + break; + + case "bid": + if(!$sender->hasPermission("economyauction.bid")) { + $sender->sendMessage(TextFormat::RED . "You don't have permission to bid."); + return true; + } + + if(!isset($args[1])) { + $sender->sendMessage(TextFormat::RED . "Usage: /auction bid "); + return true; + } + + $bidAmount = (float) $args[1]; + + if($bidAmount <= 0) { + $sender->sendMessage(TextFormat::RED . "Bid amount must be positive."); + return true; + } + + $this->placeBid($sender, $bidAmount); + break; + + case "list": + $this->showAuctions($sender); + break; + + case "end": + if(!$sender->hasPermission("economyauction.admin")) { + $sender->sendMessage(TextFormat::RED . "You don't have permission to end auctions."); + return true; + } + + $this->endCurrentAuction($sender); + break; + + default: + $sender->sendMessage(TextFormat::RED . "Usage: /auction "); + break; + } + + return true; } - if(!is_file($this->getDataFolder() . "QuitQueue.dat")) { - file_put_contents($this->getDataFolder() . "QuitQueue.dat", serialize(array())); + + return false; + } + + private function startAuction(Player $player, float $startingPrice, int $duration): void { + if(!empty($this->auctions)) { + $player->sendMessage(TextFormat::RED . "An auction is already in progress!"); + return; } - $this->auctions = unserialize(file_get_contents($this->getDataFolder() . "Auctions.dat")); - $this->queue = unserialize(file_get_contents($this->getDataFolder() . "QuitQueue.dat")); - - foreach($this->auctions as $player => $data) { - if(isset($this->auctions[$player][6])) { - $id = $this->getScheduler()->scheduleDelayedTask(new QuitAuctionTask($this, $player), $this->auctions[$player][6])->getTaskId(); - $this->auctions[$player][7] = time(); - $this->auctions[$player][8] = $id; - } + + $item = $player->getInventory()->getItemInHand(); + if($item->isNull() || $item->getCount() === 0) { + $player->sendMessage(TextFormat::RED . "You must hold an item to auction!"); + return; } + + $auctionId = uniqid(); + $endTime = time() + ($duration * 60); + + $this->auctions[$auctionId] = [ + "seller" => $player->getName(), + "item" => $item, + "starting_price" => $startingPrice, + "current_bid" => $startingPrice, + "highest_bidder" => null, + "end_time" => $endTime, + "duration" => $duration + ]; + + $player->getInventory()->setItemInHand($item->setCount(0)); + + $this->getScheduler()->scheduleDelayedTask(new QuitAuctionTask($this, $auctionId), $duration * 60 * 20); + + $this->broadcastMessage(TextFormat::GREEN . "New auction started by " . $player->getName() . "!"); + $this->broadcastMessage(TextFormat::YELLOW . "Item: " . $item->getName() . " x" . $item->getCount()); + $this->broadcastMessage(TextFormat::YELLOW . "Starting price: $" . $startingPrice); + $this->broadcastMessage(TextFormat::YELLOW . "Duration: " . $duration . " minutes"); + $this->broadcastMessage(TextFormat::AQUA . "Use /auction bid to place a bid!"); } - public function onDisable() { - $now = time(); - foreach($this->auctions as $player => $data) { - if(isset($this->auctions[$player][6])) { - $this->auctions[$player][6] -= ($now - $this->auctions[$player][7]); + private function placeBid(Player $player, float $bidAmount): void { + if(empty($this->auctions)) { + $player->sendMessage(TextFormat::RED . "No auction is currently active!"); + return; + } + + $auction = reset($this->auctions); + $auctionId = key($this->auctions); + + if($auction["seller"] === $player->getName()) { + $player->sendMessage(TextFormat::RED . "You cannot bid on your own auction!"); + return; + } + + if($bidAmount <= $auction["current_bid"]) { + $player->sendMessage(TextFormat::RED . "Your bid must be higher than the current bid of $" . $auction["current_bid"]); + return; + } + + if($this->api->myMoney($player) < $bidAmount) { + $player->sendMessage(TextFormat::RED . "You don't have enough money to place this bid!"); + return; + } + + // Return money to previous highest bidder + if($auction["highest_bidder"] !== null) { + $previousBidder = $this->getServer()->getPlayerExact($auction["highest_bidder"]); + if($previousBidder !== null) { + $this->api->addMoney($previousBidder, $auction["current_bid"]); + $previousBidder->sendMessage(TextFormat::YELLOW . "You have been outbid! Your money has been returned."); } } - file_put_contents($this->getDataFolder() . "Auctions.dat", serialize($this->auctions)); - file_put_contents($this->getDataFolder() . "QuitQueue.dat", serialize($this->queue)); + + // Take money from new bidder + $this->api->reduceMoney($player, $bidAmount); + + $this->auctions[$auctionId]["current_bid"] = $bidAmount; + $this->auctions[$auctionId]["highest_bidder"] = $player->getName(); + + $this->broadcastMessage(TextFormat::GREEN . $player->getName() . " placed a bid of $" . $bidAmount . "!"); } - public function onCommand(CommandSender $sender, Command $command, string $label, array $params): bool { - switch ($command->getName()) { - case "auction": - $sub = array_shift($params); - switch ($sub) { - case "start": - if(!$sender instanceof Player) { - $sender->sendMessage("Please run this command in-game."); - break; - } - if(isset($this->auctions[$sender->getName()])) { - $sender->sendMessage("You already have ongoing auction"); - break; - } - $tax = $this->getConfig()->get("auction-tax"); - if($tax > EconomyAPI::getInstance()->myMoney($sender)) { - $sender->sendMessage("You don't have enough money to start auction. Auction tax : " . $tax); - break; - } - - $item = array_shift($params); - $count = array_shift($params); - $startPrice = array_shift($params); - if(trim($item) === "" or !is_numeric($count) or !is_numeric($count)) { - $sender->sendMessage("Usage: /auction start "); - break; - } - - $count = (int) $count; - $item = Item::fromString($item); - - $cnt = 0; - foreach($sender->getInventory()->getContents() as $i) { - if($i->equals($item)) { - $cnt += $i->getCount(); - if($count <= $cnt) { - break; - } - } - } - if($count <= $cnt) { - $item->setCount($count); - $sender->getInventory()->removeItem($item); - - $this->auctions[strtolower($sender->getName())] = array( - $item->getID(), $item->getDamage(), $count, (float) $startPrice, null, (float) $startPrice, null, null - ); - $this->getServer()->broadcastMessage(TextFormat::GREEN . $sender->getName() . TextFormat::RESET . "'s auction has just started."); - EconomyAPI::getInstance()->reduceMoney($sender, $tax); - }else{ - $sender->sendMessage("You don't have enough items"); - } - break; - case "stop": - $auction = array_shift($params); - if(trim($auction) === "" and !$sender instanceof Player) { - $sender->sendMessage("Usage: /auction stop "); - break; - } elseif(trim($auction) === "" and $sender instanceof Player) { - $auction = $sender->getName(); - }else{ - $player = $this->getServer()->getPlayer($auction); - if($player instanceof Player) { - $auction = $player->getName(); - } - } - $auction = strtolower($auction); - if(!isset($this->auctions[$auction])) { - $sender->sendMessage((strtolower($sender->getName()) === $auction ? "You have" : "$auction has") . " no ongoing auction"); - break; - } - $this->quitAuction($auction); - $sender->sendMessage((strtolower($sender->getName()) === $auction ? "Your" : "$auction's") . " auction has successfully stopped."); - break; - case "time": - if(!$sender instanceof Player) { - $sender->sendMessage("Please run this command in-game."); - return true; - } - $item = array_shift($params); - $count = array_shift($params); - $startPrice = array_shift($params); - $time = array_shift($params); - if(trim($item) === "" or !is_numeric($count) or !is_numeric($startPrice) or !is_numeric($time)) { - $sender->sendMessage("Usage: /auction time