diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..e13b0cc --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,42 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + build: + name: PHPStan analysis + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + php: + - "8.1" + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: pmmp/setup-php-action@2.0.0 + with: + php-version: ${{ matrix.php }} + install-path: "./bin" + pm-version-major: "5" + + - name: Restore Composer package cache + id: composer-cache + uses: actions/cache@v2 + with: + path: "~/.cache/composer" + key: "php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}" + restore-keys: "php-${{ matrix.php }}-composer-" + + - name: Install PHPStan Composer dependencies + working-directory: ./tools/phpstan + run: composer install --prefer-dist --no-interaction + + - name: Run PHPStan + working-directory: ./tools/phpstan + run: vendor/bin/phpstan analyze \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ad52c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,220 @@ +.idea/ + +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +vendor/ +composer.lock +dev/ +output/ +.php-cs-fixer.cache \ No newline at end of file diff --git a/.poggit.yml b/.poggit.yml index 44fae63..a9f20aa 100644 --- a/.poggit.yml +++ b/.poggit.yml @@ -2,9 +2,16 @@ build-by-default: true branches: - stable -- dev -- sbchat +- pm5 projects: SkyBlocksPM: path: "" + libs: + - src: Paroxity/Commando/Commando + version: ^3.0.0 + - src: poggit/libasynql/libasynql + version: ^4.1.6 + - src: sylvrs/libMarshal/libMarshal + version: ^1.4.3 + branch: "feature/virion" ... diff --git a/README.md b/README.md index 4561533..e80b514 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- A SkyBlocks plugin for PocketMine-MP, with many features to offer. + A SkyBlocks plugin for PocketMine-MP, with many features to offer.

SkyBlocksPM developed by: KressentHosting @@ -19,12 +19,12 @@ SkyBlocksPM developed by: KressentHosting - [x] Custom Island support - [x] SQLITe3 & MYSQL Storage - [x] Configurable messages -- [x] Island Settings - [x] Island Members - [x] Configurable visit UI - [x] Island visit support - [x] Starting Skyblock Chests (The chests will have the same contents from the ones which were present and as well as NPCs while using the `/is setworld` command) -- [x] Settings (Such as Interact, Pickup, Place Blocks, etc.) +- [x] Island Settings (Such as Interact, Pickup, Place Blocks, etc.) +- [x] Private Island Chat # Setup @@ -35,9 +35,8 @@ SkyBlocksPM developed by: KressentHosting # Planned features -- [ ] Scoreboard support. (Maybe, slight chance) -- [ ] UI Support (Such as creating, modifying isalnds and etc) -- [ ] Private Island chat with chat format (Not officially decided yet) +- [ ] Scoreboard support. (Maybe) +- [ ] UI Support (Creating and Modifying islands, etc.) And possibly few more that isn't listed as it's in development. diff --git a/plugin.yml b/plugin.yml index 226f41c..5dc3718 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,8 +1,8 @@ name: SkyBlocksPM -api: 4.0.0 +api: 5.0.0 author: Vecnavium main: Vecnavium\SkyBlocksPM\SkyBlocksPM -version: 1.0.9 +version: 1.1.0 permissions: skyblockspm.command: diff --git a/resources/config.yml b/resources/config.yml index c55acfb..09d4589 100644 --- a/resources/config.yml +++ b/resources/config.yml @@ -1,6 +1,8 @@ #==========================================# #Main Config File for SkyBlocksPM #==========================================# +version: "1" + database: # The database type. "sqlite" and "mysql" are supported. type: sqlite @@ -18,6 +20,7 @@ database: username: root password: "" schema: skyblockspm + port: 3306 # The maximum number of simultaneous SQL queries # Recommended: 1 for sqlite, 2 for MySQL. You may want to further increase this value if your MySQL connection is very slow. worker-limit: 1 diff --git a/resources/messages.yml b/resources/messages.yml index c4a240c..390cda8 100644 --- a/resources/messages.yml +++ b/resources/messages.yml @@ -20,7 +20,6 @@ messages: player-not-online: "The player you have specified is currently not online or doesnt exist." have-sb: "You already own a SkyBlock Island" no-sb: "You do not have a SkyBlock Island to use the command." - not-registered: "The player you have specified does not exist." no-island: "The specified player does not own an island." no-default-island: "The default island has not been set, please ask the server staff to use the '/sb setworld' command to set the island world" no-sb-go: "You do not own a SkyBlock island" diff --git a/src/Vecnavium/SkyBlocksPM/CheckUpdateTask.php b/src/Vecnavium/SkyBlocksPM/CheckUpdateTask.php index 2c843af..f1bb546 100644 --- a/src/Vecnavium/SkyBlocksPM/CheckUpdateTask.php +++ b/src/Vecnavium/SkyBlocksPM/CheckUpdateTask.php @@ -13,24 +13,25 @@ class CheckUpdateTask extends AsyncTask { - private const POGGIT_RELEASES_URL = "https://poggit.pmmp.io/releases.min.json?name="; + private const POGGIT_RELEASES_URL = 'https://poggit.pmmp.io/releases.min.json?name='; - public function __construct(private string $pluginName, private string $pluginVersion) { - } + public function __construct(private string $pluginName, private string $pluginVersion) {} public function onRun() : void { $json = Internet::getURL(self::POGGIT_RELEASES_URL . $this->pluginName, 10, [], $err); $highestVersion = $this->pluginVersion; - $artifactUrl = ""; - $api = ""; + $artifactUrl = ''; + $api = ''; if($json !== null) { $releases = json_decode($json->getBody(), true); - foreach($releases as $release) { - if(version_compare($highestVersion, $release["version"], ">=")) continue; - - $highestVersion = $release["version"]; - $artifactUrl = $release["artifact_url"]; - $api = $release["api"][0]["from"] . " - " . $release["api"][0]["to"]; + if($releases !== null) { + foreach ($releases as $release) { + if (version_compare($highestVersion, $release['version'], '>=')) continue; + + $highestVersion = $release['version']; + $artifactUrl = $release['artifact_url']; + $api = $release['api'][0]['from'] . ' - ' . $release['api'][0]['to']; + } } } @@ -50,8 +51,8 @@ public function onCompletion() : void { } if($highestVersion !== $this->pluginVersion) { - $artifactUrl = $artifactUrl . "/" . $this->pluginName . "_" . $highestVersion . ".phar"; - $plugin->getLogger()->notice(vsprintf("SkyBlocksPM %s has been released for API %s. Download the new update at %s", [$highestVersion, $api, $artifactUrl])); + $artifactUrl = $artifactUrl . '/' . $this->pluginName . '_' . $highestVersion . '.phar'; + $plugin->getLogger()->notice(vsprintf('SkyBlocksPM %s has been released for API %s. Download the new update at %s', [$highestVersion, $api, $artifactUrl])); } } } diff --git a/src/Vecnavium/SkyBlocksPM/SkyBlocksPM.php b/src/Vecnavium/SkyBlocksPM/SkyBlocksPM.php index 260c3dc..2b0edb9 100644 --- a/src/Vecnavium/SkyBlocksPM/SkyBlocksPM.php +++ b/src/Vecnavium/SkyBlocksPM/SkyBlocksPM.php @@ -4,27 +4,42 @@ namespace Vecnavium\SkyBlocksPM; -use pocketmine\player\Player as P; -use pocketmine\utils\Config; +use CortexPE\Commando\BaseCommand; +use CortexPE\Commando\PacketHooker; +use libMarshal\exception\GeneralMarshalException; +use libMarshal\exception\UnmarshalException; +use libMarshal\MarshalTrait; +use pocketmine\player\Player; +use pocketmine\plugin\DisablePluginException; +use pocketmine\plugin\PluginBase; +use pocketmine\utils\Config as PMConfig; +use pocketmine\utils\ConfigLoadException; +use pocketmine\utils\SingletonTrait; +use poggit\libasynql\DataConnector; +use poggit\libasynql\libasynql; use Vecnavium\SkyBlocksPM\commands\SkyBlockCommand; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\PacketHooker; +use Vecnavium\SkyBlocksPM\config\Config; +use Vecnavium\SkyBlocksPM\config\database\DatabaseConfig; use Vecnavium\SkyBlocksPM\generator\Generator; use Vecnavium\SkyBlocksPM\invites\InviteManager; use Vecnavium\SkyBlocksPM\listener\EventListener; use Vecnavium\SkyBlocksPM\messages\Messages; -use Vecnavium\SkyBlocksPM\skyblock\SkyBlockManager; use Vecnavium\SkyBlocksPM\player\PlayerManager; -use pocketmine\plugin\PluginBase; -use Vecnavium\SkyBlocksPM\libs\poggit\libasynql\DataConnector; -use Vecnavium\SkyBlocksPM\libs\poggit\libasynql\libasynql; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlockManager; use function array_search; +use function class_exists; use function rename; +use function strval; +use function trait_exists; use function version_compare; class SkyBlocksPM extends PluginBase { - const MSG_VER = "1"; - const FORM_VER = "1"; + use SingletonTrait; + + const CFG_VER = '1'; + const MSG_VER = '1'; + const FORM_VER = '1'; private DataConnector $dataConnector; private Generator $generator; @@ -32,21 +47,29 @@ class SkyBlocksPM extends PluginBase { private PlayerManager $playerManager; private SkyBlockManager $SkyBlockManager; private InviteManager $inviteManager; - private static self $instance; - /** @var P[] */ - private array $chat; + private Config $config; - protected function onLoad(): void { - self::$instance = $this; - } + /** @var string[] */ + private array $chat; public function onEnable(): void { - if (!PacketHooker::isRegistered()) - PacketHooker::register($this); + self::setInstance($this); + $this->checkVirions(); + + if (!PacketHooker::isRegistered()) PacketHooker::register($this); + $this->saveDefaultConfig(); $this->saveResource('messages.yml'); $this->saveResource('forms.yml'); $this->checkConfigs(); + + try{ + $this->config = Config::unmarshal($this->getConfig()->getAll()); + }catch(GeneralMarshalException|UnmarshalException|ConfigLoadException $e){ + $this->getLogger()->error($e->getMessage()); + throw new DisablePluginException; + } + $this->initDataBase(); $this->getServer()->getPluginManager()->registerEvents(new EventListener($this), $this); $this->generator = new Generator($this); @@ -54,11 +77,12 @@ public function onEnable(): void { $this->playerManager = new PlayerManager($this); $this->SkyBlockManager = new SkyBlockManager($this); $this->inviteManager = new InviteManager(); - $this->getServer()->getCommandMap()->register('SkyBlocksPM', new SkyBlockCommand($this, 'skyblock', 'The core command for SkyBlocks', ['sb', 'is'])); - @mkdir($this->getDataFolder() . "cache"); - @mkdir($this->getDataFolder() . "cache/island"); - $this->checkUpdate(); + $this->getServer()->getCommandMap()->register('SkyBlocksPM', new SkyBlockCommand($this)); + @mkdir($this->getDataFolder() . 'cache'); + @mkdir($this->getDataFolder() . 'cache/island'); $this->chat = []; + + $this->getServer()->getAsyncPool()->submitTask(new CheckUpdateTask($this->getDescription()->getName(), $this->getDescription()->getVersion())); } public function onDisable(): void { @@ -66,30 +90,49 @@ public function onDisable(): void { $this->dataConnector->close(); } + /** + * @return void + * + * @credit JavierLeon9966 + */ public function initDataBase(): void { - $db = libasynql::create($this, $this->getConfig()->get('database'), ['mysql' => 'mysql.sql', 'sqlite' => 'sqlite.sql']); + $databaseConfig = $this->config->database ?? new DatabaseConfig(); + $friendlyConfig = [ + 'type' => $databaseConfig->type, + 'sqlite' => [ + 'file' => $databaseConfig->sqlite->file + ], + 'mysql' => [ + 'host' => $databaseConfig->mysql->host, + 'username' => $databaseConfig->mysql->username, + 'password' => $databaseConfig->mysql->password, + 'schema' => $databaseConfig->mysql->schema, + 'port' => $databaseConfig->mysql->port + ], + 'worker-limit' => $databaseConfig->type !== 'sqlite' ? $databaseConfig->workerLimit : 1 + ]; + + $db = libasynql::create($this, $friendlyConfig, [ + 'mysql' => 'mysql.sql', + 'sqlite' => 'sqlite.sql' + ]); $db->executeGeneric('skyblockspm.player.init'); $db->executeGeneric('skyblockspm.sb.init'); $db->waitAll(); $this->dataConnector = $db; } + /** + * @return string[] + */ public function getChat(): array { return $this->chat; } - public function addPlayerToChat(P $player): void { - $this->chat[] = $player->getName(); - } - - public function removePlayerFromChat(P $player): void { - unset($this->chat[array_search($player->getName(), $this->chat)]); + public function setPlayerChat(Player $player, bool $status): void{ + if($status) $this->chat[] = $player->getName(); + else unset($this->chat[array_search($player->getName(), $this->chat, true)]); } - - public function checkUpdate(): void { - $this->getServer()->getAsyncPool()->submitTask(new CheckUpdateTask($this->getDescription()->getName(), $this->getDescription()->getVersion())); - } - /** * @return DataConnector @@ -133,29 +176,49 @@ public function getInviteManager(): InviteManager { return $this->inviteManager; } - public function checkConfigs() { - $messagesCfg = new Config($this->getDataFolder() . "messages.yml", Config::YAML); - if(version_compare($messagesCfg->get("version", "0"), self::MSG_VER, "<>")) { - $this->getLogger()->error("Your message files are outdated. SkyBlocksPM will automatically create a new config."); - $this->getLogger()->error("The old message files can be found at 'messages.old.yml'"); - rename($this->getDataFolder() . "messages.yml", $this->getDataFolder() . "messages.old.yml"); + public function checkConfigs(): void { + if(version_compare(strval($this->getConfig()->get('version', '0')), self::CFG_VER, '<>')) { + $this->getLogger()->error('Your config file is outdated. SkyBlocksPM will automatically create a new config.'); + $this->getLogger()->error('The old config file can be found at "config.old.yml"'); + rename($this->getDataFolder() . 'config.yml', $this->getDataFolder() . 'config.old.yml'); + $this->saveDefaultConfig(); + $this->getConfig()->reload(); + } + + $messagesCfg = new PMConfig($this->getDataFolder() . 'messages.yml', PMConfig::YAML); + if(version_compare(strval($messagesCfg->get('version', '0')), self::MSG_VER, '<>')) { + $this->getLogger()->error('Your message files are outdated. SkyBlocksPM will automatically create a new config.'); + $this->getLogger()->error('The old message files can be found at "messages.old.yml"'); + rename($this->getDataFolder() . 'messages.yml', $this->getDataFolder() . 'messages.old.yml'); $this->saveResource('messages.yml'); $messagesCfg->reload(); } - $formsCfg = new Config($this->getDataFolder() . "forms.yml", Config::YAML); - if(version_compare($formsCfg->get("version", "0"), self::FORM_VER, "<>")) { - $this->getLogger()->error("Your form message files are outdated. SkyBlocksPM will automatically create a new config."); - $this->getLogger()->error("The old form message files can be found at 'forms.old.yml'"); - rename($this->getDataFolder() . "forms.yml", $this->getDataFolder() . "forms.old.yml"); + $formsCfg = new PMConfig($this->getDataFolder() . 'forms.yml', PMConfig::YAML); + if(version_compare(strval($formsCfg->get('version', '0')), self::FORM_VER, '<>')) { + $this->getLogger()->error('Your form message files are outdated. SkyBlocksPM will automatically create a new config.'); + $this->getLogger()->error('The old form message files can be found at "forms.old.yml"'); + rename($this->getDataFolder() . 'forms.yml', $this->getDataFolder() . 'forms.old.yml'); $this->saveResource('forms.yml'); $formsCfg->reload(); } } - /** - * @return self - */ - public static function getInstance(): self { - return self::$instance; + public function checkVirions(): void{ + if(!class_exists(libasynql::class)) { + $this->getLogger()->error('Virion "libasynql" was not found. Please download SkyBlocksPM from Poggit-CI for the plugin to work correctly.'); + throw new DisablePluginException; + } + if(!class_exists(BaseCommand::class)) { + $this->getLogger()->error('Virion "Commando" was not found. Please download SkyBlocksPM from Poggit-CI for the plugin to work correctly.'); + throw new DisablePluginException; + } + if(!trait_exists(MarshalTrait::class)) { + $this->getLogger()->error('Virion "libMarshal" was not found. Please download SkyBlocksPM from Poggit-CI for the plugin to work correctly.'); + throw new DisablePluginException; + } + } + + public function getNewConfig(): Config{ + return $this->config; } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/SkyBlockCommand.php b/src/Vecnavium/SkyBlocksPM/commands/SkyBlockCommand.php index e21a5a5..e6c4bb3 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/SkyBlockCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/SkyBlockCommand.php @@ -4,38 +4,52 @@ namespace Vecnavium\SkyBlocksPM\commands; +use CortexPE\Commando\BaseCommand; +use pocketmine\command\CommandSender; +use pocketmine\plugin\PluginBase; +use Vecnavium\SkyBlocksPM\commands\subcommands\AcceptSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\ChatSubCommand; +use Vecnavium\SkyBlocksPM\commands\subcommands\CreateSubCommand; +use Vecnavium\SkyBlocksPM\commands\subcommands\DeleteSubCommand; +use Vecnavium\SkyBlocksPM\commands\subcommands\InviteSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\KickSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\LeaveSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\SettingsSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\SetWorldCommand; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseCommand; -use Vecnavium\SkyBlocksPM\commands\subcommands\AcceptSubCommand; -use Vecnavium\SkyBlocksPM\commands\subcommands\CreateSubCommand; -use Vecnavium\SkyBlocksPM\commands\subcommands\DeleteSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\TpSubCommand; -use Vecnavium\SkyBlocksPM\commands\subcommands\InviteSubCommand; use Vecnavium\SkyBlocksPM\commands\subcommands\VisitSubCommand; -use pocketmine\command\CommandSender; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class SkyBlockCommand extends BaseCommand { + public function __construct(SkyBlocksPM $plugin){ + parent::__construct($plugin, 'skyblock', 'The core command for SkyBlocks', ['sb', 'is']); + } + public function prepare(): void { $this->setPermission('skyblockspm.command'); - $this->registerSubCommand(new AcceptSubCommand('accept', 'Accept the incoming invite to a SkyBlock Island')); - $this->registerSubCommand(new ChatSubCommand('chat', 'Chat with your SkyBlock Island members')); - $this->registerSubCommand(new CreateSubCommand('create', 'Create your own SkyBlock Island')); - $this->registerSubCommand(new DeleteSubCommand('delete', 'Delete a users SkyBlock Island', ['disband'])); - $this->registerSubCommand(new KickSubCommand('kick', 'Kick a member from your SkyBlock Island')); - $this->registerSubCommand(new LeaveSubCommand('leave', 'Leave your current SkyBlock Island')); - $this->registerSubCommand(new SettingsSubCommand('settings', 'Edit your SkyBlock Island settings')); - $this->registerSubCommand(new SetWorldCommand('setworld', 'Sets the current world as the SkyBlock World which will be copied to newer worlds upon Island creation')); - $this->registerSubCommand(new TpSubCommand('tp', 'Teleport to a users SkyBlock Island', ['go', 'home'])); - $this->registerSubCommand(new InviteSubCommand('invite', 'Invites the player to your SkyBlock Island')); - $this->registerSubCommand(new VisitSubCommand('visit', 'Visit a players SkyBlock Island')); + $this->registerSubCommand(new AcceptSubCommand($this->plugin, 'accept', 'Accept the incoming invite to a SkyBlock Island')); + $this->registerSubCommand(new ChatSubCommand($this->plugin, 'chat', 'Chat with your SkyBlock Island members')); + $this->registerSubCommand(new CreateSubCommand($this->plugin, 'create', 'Create your own SkyBlock Island')); + $this->registerSubCommand(new DeleteSubCommand($this->plugin, 'delete', 'Delete a users SkyBlock Island', ['disband'])); + $this->registerSubCommand(new KickSubCommand($this->plugin, 'kick', 'Kick a member from your SkyBlock Island')); + $this->registerSubCommand(new LeaveSubCommand($this->plugin, 'leave', 'Leave your current SkyBlock Island')); + $this->registerSubCommand(new SettingsSubCommand($this->plugin, 'settings', 'Edit your SkyBlock Island settings')); + $this->registerSubCommand(new SetWorldCommand($this->plugin, 'setworld', 'Sets the current world as the SkyBlock World which will be copied to newer worlds upon Island creation')); + $this->registerSubCommand(new TpSubCommand($this->plugin, 'tp', 'Teleport to a users SkyBlock Island', ['go', 'home'])); + $this->registerSubCommand(new InviteSubCommand($this->plugin, 'invite', 'Invites the player to your SkyBlock Island')); + $this->registerSubCommand(new VisitSubCommand($this->plugin, 'visit', 'Visit a players SkyBlock Island')); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + $this->sendUsage(); } - } diff --git a/src/Vecnavium/SkyBlocksPM/commands/args/PlayerArgument.php b/src/Vecnavium/SkyBlocksPM/commands/args/PlayerArgument.php new file mode 100644 index 0000000..65ecaba --- /dev/null +++ b/src/Vecnavium/SkyBlocksPM/commands/args/PlayerArgument.php @@ -0,0 +1,50 @@ +getPlayerExact($argument); + if($player !== null){ + return $player; + } + return $argument; + } + + /** + * @return string + */ + public function getTypeName(): string{ + return 'player'; + } +} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/AcceptSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/AcceptSubCommand.php index 91a8adc..b9b5fe8 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/AcceptSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/AcceptSubCommand.php @@ -4,46 +4,59 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\player\Player; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\invites\Invite; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; use pocketmine\player\Player as P; +use Vecnavium\SkyBlocksPM\commands\args\PlayerArgument; +use Vecnavium\SkyBlocksPM\invites\Invite; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use function strval; class AcceptSubCommand extends BaseSubCommand { protected function prepare(): void { $this->setPermission('skyblockspm.accept'); - $this->registerArgument(0, new RawStringArgument('name')); + $this->registerArgument(0, new PlayerArgument('player')); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); - $invite = $plugin->getInviteManager()->getPlayerInvites($args['name']); + $invite = $plugin->getInviteManager()->getPlayerInvites(($args['player'] instanceof P ? $args['player']->getName() : strval($args['player']))); if (!$invite instanceof Invite) return; if (!$invite->handleInvite()) return; $plugin->getInviteManager()->cancelInvite($invite->getId()); - $player = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); - $inviter = $plugin->getPlayerManager()->getPlayerByPrefix($invite->getInviter()->getName()); + $player = $plugin->getPlayerManager()->getPlayer($sender->getName()); + $inviter = $plugin->getPlayerManager()->getPlayer($invite->getInviter()->getName()); if($player instanceof Player && $inviter instanceof Player) { $player->setSkyBlock($inviter->getSkyBlock()); $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($inviter->getSkyBlock()); - $members = $skyblock->getMembers(); - array_push($members, $sender->getName()); - $skyblock->setMembers($members); - foreach ($skyblock->getMembers() as $member) { - $mbr = $plugin->getServer()->getPlayerByPrefix($member); - if ($mbr instanceof P) - $mbr->sendMessage($plugin->getMessages()->getMessage('invite-accepted', [ - "{PLAYER}" => $sender->getName() - ])); + if($skyblock instanceof SkyBlock) { + $members = $skyblock->getMembers(); + $members[] = $sender->getName(); + $skyblock->setMembers($members); + foreach ($skyblock->getMembers() as $member) { + $mbr = $plugin->getServer()->getPlayerExact($member); + if ($mbr instanceof P) { + $mbr->sendMessage($plugin->getMessages()->getMessage('invite-accepted', [ + '{PLAYER}' => $sender->getName() + ])); + } + } } } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/ChatSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/ChatSubCommand.php index 580131b..dda0685 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/ChatSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/ChatSubCommand.php @@ -2,28 +2,36 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use pocketmine\player\Player as P; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; +use pocketmine\player\Player as P; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use function in_array; class ChatSubCommand extends BaseSubCommand { protected function prepare(): void { - $this->setPermission("skyblockspm.chat"); + $this->setPermission('skyblockspm.chat'); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); if (!$sender instanceof P) return; - if (!in_array($sender->getName(), $plugin->getChat())) - $plugin->addPlayerToChat($sender); - else - $plugin->removePlayerFromChat($sender); - $sender->sendMessage($plugin->getMessages()->getMessage("toggle-chat")); + $chatStatus = in_array($sender->getName(), $plugin->getChat(), true); + $plugin->setPlayerChat($sender, !$chatStatus); + + $sender->sendMessage($plugin->getMessages()->getMessage('toggle-chat')); } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/CreateSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/CreateSubCommand.php index a7e9f08..a72af46 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/CreateSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/CreateSubCommand.php @@ -4,15 +4,15 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use pocketmine\block\VanillaBlocks; +use CortexPE\Commando\args\RawStringArgument; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; -use pocketmine\player\Player; -use pocketmine\player\PlayerChunkLoader; -use pocketmine\world\Position; +use pocketmine\player\Player as P; +use pocketmine\utils\Utils; use Ramsey\Uuid\Uuid; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use function strval; class CreateSubCommand extends BaseSubCommand { @@ -21,25 +21,35 @@ protected function prepare(): void { $this->registerArgument(0, new RawStringArgument('name')); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); - if (!$sender instanceof Player) return; + if (!$sender instanceof P) return; + + $player = $plugin->getPlayerManager()->getPlayer($sender->getName()); + if(!$player instanceof Player) return; - $player = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); if ($player->getSkyBlock() !== '') { $sender->sendMessage($plugin->getMessages()->getMessage('have-sb')); return; } - if (count(array_diff(scandir($plugin->getDataFolder() . 'cache/island'), ['..', "."])) == 0) { - $sender->sendMessage($plugin->getMessages()->getMessage("no-default-island")); + if (count(array_diff(Utils::assumeNotFalse(scandir($plugin->getDataFolder() . 'cache/island')), ['..', '.'])) == 0) { + $sender->sendMessage($plugin->getMessages()->getMessage('no-default-island')); return; } $sender->sendMessage($plugin->getMessages()->getMessage('skyblock-creating')); $id = Uuid::uuid4()->toString(); $player->setSkyBlock($id); - $plugin->getGenerator()->generateIsland($sender, $id, $args['name']); + $plugin->getGenerator()->generateIsland($sender, $id, strval($args['name'])); // Name validation? } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/DeleteSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/DeleteSubCommand.php index cb75782..7e390ed 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/DeleteSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/DeleteSubCommand.php @@ -4,12 +4,17 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\player\Player; -use pocketmine\player\Player as P; +use CortexPE\Commando\args\RawStringArgument; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; +use pocketmine\player\Player as P; +use pocketmine\utils\Filesystem; +use pocketmine\utils\Utils; +use pocketmine\world\World; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use function strval; class DeleteSubCommand extends BaseSubCommand { @@ -17,32 +22,45 @@ protected function prepare(): void { $this->setPermission('skyblockspm.delete'); $this->registerArgument(0, new RawStringArgument('name')); } - + + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); - $name = $args['name']; + $name = strval($args['name']); if ($name !== $sender->getName() && !$sender->hasPermission('skyblockspm.deleteothers')) { $sender->sendMessage($plugin->getMessages()->getMessage('no-perms-delete')); return; } - $skyblockPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($name); + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($name); if (!$skyblockPlayer instanceof Player) { - $sender->sendMessage($plugin->getMessages()->getMessage('not-registered')); + $sender->sendMessage($plugin->getMessages()->getMessage('player-not-online')); return; } if ($skyblockPlayer->getSkyBlock() == '') { $sender->sendMessage($plugin->getMessages()->getMessage('no-island')); return; } + $defaultWorld = $plugin->getServer()->getWorldManager()->getDefaultWorld(); + if(!$defaultWorld instanceof World) return; + $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblockPlayer->getSkyBlock()); + if(!$skyblock instanceof SkyBlock) return; + foreach ($skyblock->getMembers() as $member) { $player = $plugin->getServer()->getPlayerExact($member); if ($player instanceof P) { - $player->teleport($plugin->getServer()->getWorldManager()->getDefaultWorld()->getSpawnLocation()); + $player->teleport($defaultWorld->getSpawnLocation()); } - if(($mPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($member)) instanceof Player) { + if(($mPlayer = $plugin->getPlayerManager()->getPlayer($member)) instanceof Player) { $mPlayer->setSkyBlock(''); } else { // Hacky but it works. @@ -51,28 +69,18 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo } $plugin->getSkyBlockManager()->deleteSkyBlock($skyblock->getName()); $world = $plugin->getServer()->getWorldManager()->getWorldByName($skyblock->getWorld()); - foreach ($world->getPlayers() as $p) { - $p->teleport($plugin->getServer()->getWorldManager()->getDefaultWorld()->getSpawnLocation()); - } - if ($world->isLoaded()) { - $folderName = $world->getFolderName(); - $plugin->getServer()->getWorldManager()->unloadWorld($world); - $this->deleteWorld($plugin->getServer()->getDataPath() . 'worlds' . DIRECTORY_SEPARATOR . $folderName); + if($world instanceof World) { + foreach ($world->getPlayers() as $p) { + $p->teleport($defaultWorld->getSpawnLocation()); + } + if ($world->isLoaded()) { + $folderName = $world->getFolderName(); + $plugin->getServer()->getWorldManager()->unloadWorld($world); + Filesystem::recursiveUnlink($plugin->getServer()->getDataPath() . 'worlds' . DIRECTORY_SEPARATOR . $folderName); + } } $sender->sendMessage($plugin->getMessages()->getMessage('deleted-sb', [ - "{NAME}" => $skyblockPlayer->getName() + '{NAME}' => $skyblockPlayer->getName() ])); } - - public function deleteWorld(string $path): void { - foreach (array_diff(scandir($path . DIRECTORY_SEPARATOR), ['..', '.']) as $file) { - if (is_dir($path . DIRECTORY_SEPARATOR . $file)) { - $this->deleteWorld($path . DIRECTORY_SEPARATOR . $file . DIRECTORY_SEPARATOR); - } else { - unlink($path . DIRECTORY_SEPARATOR . $file); - } - } - rmdir($path); - } - } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/InviteSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/InviteSubCommand.php index 14b7c31..274eb6a 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/InviteSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/InviteSubCommand.php @@ -4,45 +4,56 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; -use pocketmine\player\Player; +use pocketmine\player\Player as P; use pocketmine\scheduler\ClosureTask; use Ramsey\Uuid\Uuid; +use Vecnavium\SkyBlocksPM\commands\args\PlayerArgument; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class InviteSubCommand extends BaseSubCommand { protected function prepare(): void { $this->setPermission('skyblockspm.invite'); - $this->registerArgument(0, new RawStringArgument('name')); + $this->registerArgument(0, new PlayerArgument('player')); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); - if (!$sender instanceof Player) return; + if (!$sender instanceof P) return; if (!$plugin->getInviteManager()->canInvite($sender)) { $sender->sendMessage($plugin->getMessages()->getMessage('invite-pending')); return; } - $player = $plugin->getServer()->getPlayerByPrefix($args['name']); - $skyblockPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); + $player = $args['player']; + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($sender->getName()); + if(!$skyblockPlayer instanceof Player) return; + $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblockPlayer->getSkyBlock()); if (!$skyblock instanceof SkyBlock) { $sender->sendMessage($plugin->getMessages()->getMessage('no-sb')); return; } - if (count($skyblock->getMembers()) >= $plugin->getConfig()->getNested('settings.max-members')) { + if (count($skyblock->getMembers()) >= $plugin->getNewConfig()->settings->maxMembers) { $sender->sendMessage($plugin->getMessages()->getMessage('member-limit')); return; } - if (!$player instanceof Player) { - $plugin->getMessages()->getMessage('player-not-online'); + if (!$player instanceof P) { + $sender->sendMessage($plugin->getMessages()->getMessage('player-not-online')); return; } if ($sender === $player) return; @@ -50,15 +61,15 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $id = Uuid::uuid4()->toString(); $plugin->getInviteManager()->addInvite($id, $sender, $player); $player->sendMessage($plugin->getMessages()->getMessage('invite-get', [ - "{INVITER}" => $sender->getName() + '{INVITER}' => $sender->getName() ])); $sender->sendMessage($plugin->getMessages()->getMessage('invite-sent', [ - "{PLAYER}" => $player->getName() + '{PLAYER}' => $player->getName() ])); $plugin->getScheduler()->scheduleDelayedTask(new ClosureTask(function () use ($plugin, $id): void { if($plugin->getInviteManager()->isInviteValid($id)) $plugin->getInviteManager()->cancelInvite($id, true); - }), $plugin->getConfig()->getNested('settings.invite-timeout', 30) * 20); + }), $plugin->getNewConfig()->settings->inviteTimeout * 20); } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/KickSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/KickSubCommand.php index 89224d0..f81dc80 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/KickSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/KickSubCommand.php @@ -4,33 +4,44 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; +use CortexPE\Commando\BaseSubCommand; +use pocketmine\command\CommandSender; +use pocketmine\player\Player as P; +use Vecnavium\SkyBlocksPM\commands\args\PlayerArgument; +use Vecnavium\SkyBlocksPM\player\Player; use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\player\Player; -use pocketmine\player\Player as P; -use pocketmine\command\CommandSender; use function array_search; use function in_array; +use function strval; class KickSubCommand extends BaseSubCommand { protected function prepare(): void { $this->setPermission('skyblockspm.kick'); - $this->registerArgument(0, new RawStringArgument('name', false)); + $this->registerArgument(0, new PlayerArgument('player')); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); if (!$sender instanceof P) return; - $toKickPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($args['name']); - $skyblockPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); + $toKickPlayer = $plugin->getPlayerManager()->getPlayer(($args['player'] instanceof P ? $args['player']->getName() : strval($args['player']))); + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($sender->getName()); + if(!$skyblockPlayer instanceof Player) return; + if (!$toKickPlayer instanceof Player) { - $sender->sendMessage($plugin->getMessages()->getMessage('not-registered')); + $sender->sendMessage($plugin->getMessages()->getMessage('player-not-online')); return; } if ($skyblockPlayer->getSkyBlock() == '') { @@ -45,20 +56,21 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo } $members = $skyblock->getMembers(); - if(!in_array($toKickPlayer->getName(), $members)){ + if(!in_array($toKickPlayer->getName(), $members, true)){ $sender->sendMessage($plugin->getMessages()->getMessage('not-member')); return; } $toKickPlayer->setSkyBlock(''); $members = $skyblock->getMembers(); - unset($members[array_search($toKickPlayer->getName(), $members)]); + unset($members[array_search($toKickPlayer->getName(), $members, true)]); $skyblock->setMembers($members); foreach ($skyblock->getMembers() as $member) { - $mbr = $plugin->getServer()->getPlayerByPrefix($member); - if ($mbr instanceof P) + $mbr = $plugin->getServer()->getPlayerExact($member); + if ($mbr instanceof P) { $mbr->sendMessage($plugin->getMessages()->getMessage('member-kicked', [ - "{PLAYER}" => $toKickPlayer->getName() + '{PLAYER}' => $toKickPlayer->getName() ])); + } } } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/LeaveSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/LeaveSubCommand.php index 6b394db..203bb42 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/LeaveSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/LeaveSubCommand.php @@ -4,12 +4,12 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; +use CortexPE\Commando\BaseSubCommand; +use pocketmine\command\CommandSender; +use pocketmine\player\Player as P; +use Vecnavium\SkyBlocksPM\player\Player; use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\player\Player; -use pocketmine\player\Player as P; -use pocketmine\command\CommandSender; use function array_search; class LeaveSubCommand extends BaseSubCommand { @@ -18,13 +18,21 @@ protected function prepare(): void { $this->setPermission('skyblockspm.leave'); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); if (!$sender instanceof P) return; - $skyblockPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($sender->getName()); if (!$skyblockPlayer instanceof Player) return; if ($skyblockPlayer->getSkyBlock() == '') { @@ -39,14 +47,15 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo } $skyblockPlayer->setSkyBlock(''); $members = $skyblock->getMembers(); - unset($members[array_search($sender->getName(), $members)]); + unset($members[array_search($sender->getName(), $members, true)]); $skyblock->setMembers($members); foreach ($skyblock->getMembers() as $member) { - $mbr = $plugin->getServer()->getPlayerByPrefix($member); - if ($mbr instanceof P) + $mbr = $plugin->getServer()->getPlayerExact($member); + if ($mbr instanceof P) { $mbr->sendMessage($plugin->getMessages()->getMessage('member-left', [ - "{PLAYER}" => $sender->getName() + '{PLAYER}' => $sender->getName() ])); + } } } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/SetWorldCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/SetWorldCommand.php index 399f8ce..2427639 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/SetWorldCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/SetWorldCommand.php @@ -4,8 +4,8 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; use pocketmine\player\Player; use Vecnavium\SkyBlocksPM\SkyBlocksPM; @@ -15,6 +15,14 @@ protected function prepare(): void { $this->setPermission('skyblockspm.setworld'); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/SettingsSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/SettingsSubCommand.php index 41cb27d..158120a 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/SettingsSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/SettingsSubCommand.php @@ -4,17 +4,18 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; +use CortexPE\Commando\BaseSubCommand; +use pocketmine\command\CommandSender; +use pocketmine\player\Player as P; use pocketmine\utils\Config; use pocketmine\utils\TextFormat; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; use Vecnavium\SkyBlocksPM\libs\jojoe77777\FormAPI\CustomForm; +use Vecnavium\SkyBlocksPM\player\Player; use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; use Vecnavium\SkyBlocksPM\skyblock\SkyblockSettingTypes; use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\player\Player; -use pocketmine\player\Player as P; -use pocketmine\command\CommandSender; use function array_shift; +use function strval; class SettingsSubCommand extends BaseSubCommand { @@ -22,13 +23,21 @@ protected function prepare(): void { $this->setPermission('skyblockspm.settings'); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); if (!$sender instanceof P) return; - $skyblockPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName()); + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($sender->getName()); if (!$skyblockPlayer instanceof Player) return; if ($skyblockPlayer->getSkyBlock() == '') { @@ -59,16 +68,16 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $player->sendMessage($plugin->getMessages()->getMessage('updated-settings')); }); $formConfig = new Config($plugin->getDataFolder() . 'forms.yml', Config::YAML); - $settingsForm->setTitle(TextFormat::colorize($formConfig->getNested('settings.title'))); - $settingsForm->addLabel(TextFormat::colorize($formConfig->getNested('settings.text'))); + $settingsForm->setTitle(TextFormat::colorize(strval($formConfig->getNested('settings.title')))); + $settingsForm->addLabel(TextFormat::colorize(strval($formConfig->getNested('settings.text')))); - $settingsForm->addToggle("Open for Visiting", $skyblock->getSetting(SkyblockSettingTypes::SETTING_VISIT)); - $settingsForm->addToggle("PvP", $skyblock->getSetting(SkyblockSettingTypes::SETTING_PVP)); - $settingsForm->addToggle("Open Chests", $skyblock->getSetting(SkyblockSettingTypes::SETTING_INTERACT_CHEST)); - $settingsForm->addToggle("Open Doors", $skyblock->getSetting(SkyblockSettingTypes::SETTING_INTERACT_DOOR)); - $settingsForm->addToggle("Pickup Items", $skyblock->getSetting(SkyblockSettingTypes::SETTING_PICKUP)); - $settingsForm->addToggle("Break Blocks", $skyblock->getSetting(SkyblockSettingTypes::SETTING_BREAK)); - $settingsForm->addToggle("Place Blocks", $skyblock->getSetting(SkyblockSettingTypes::SETTING_PLACE)); + $settingsForm->addToggle('Open for Visiting', $skyblock->getSetting(SkyblockSettingTypes::SETTING_VISIT)); + $settingsForm->addToggle('PvP', $skyblock->getSetting(SkyblockSettingTypes::SETTING_PVP)); + $settingsForm->addToggle('Open Chests', $skyblock->getSetting(SkyblockSettingTypes::SETTING_INTERACT_CHEST)); + $settingsForm->addToggle('Open Doors', $skyblock->getSetting(SkyblockSettingTypes::SETTING_INTERACT_DOOR)); + $settingsForm->addToggle('Pickup Items', $skyblock->getSetting(SkyblockSettingTypes::SETTING_PICKUP)); + $settingsForm->addToggle('Break Blocks', $skyblock->getSetting(SkyblockSettingTypes::SETTING_BREAK)); + $settingsForm->addToggle('Place Blocks', $skyblock->getSetting(SkyblockSettingTypes::SETTING_PLACE)); $sender->sendForm($settingsForm); } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/TpSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/TpSubCommand.php index e6e0734..fb96458 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/TpSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/TpSubCommand.php @@ -4,11 +4,14 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; -use pocketmine\player\Player; +use pocketmine\player\Player as P; use pocketmine\world\Position; +use pocketmine\world\World; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class TpSubCommand extends BaseSubCommand { @@ -16,18 +19,30 @@ protected function prepare(): void { $this->setPermission('skyblockspm.tp'); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); + $skyblockPlayer = $plugin->getPlayerManager()->getPlayer($sender->getName()); - if (!$sender instanceof Player) return; + if (!$sender instanceof P || !$skyblockPlayer instanceof Player) return; - $skyblock = $plugin->getPlayerManager()->getPlayerByPrefix($sender->getName())->getSkyblock(); - if ($skyblock == '') { + if ($skyblockPlayer->getSkyBlock() == '') { $sender->sendMessage($plugin->getMessages()->getMessage('no-sb-go')); return; } - $spawn = $plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblock)->getSpawn(); - $sender->teleport(Position::fromObject($spawn->up(), $plugin->getServer()->getWorldManager()->getWorldByName($plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblock)->getWorld()))); + $skyblockIsland = $plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblockPlayer->getSkyBlock()); + if(!$skyblockIsland instanceof SkyBlock) return; + $skyblockWorld = $plugin->getServer()->getWorldManager()->getWorldByName($skyblockIsland->getWorld()); + if(!$skyblockWorld instanceof World) return; + + $sender->teleport(Position::fromObject($skyblockIsland->getSpawn()->up(), $skyblockWorld)); } } diff --git a/src/Vecnavium/SkyBlocksPM/commands/subcommands/VisitSubCommand.php b/src/Vecnavium/SkyBlocksPM/commands/subcommands/VisitSubCommand.php index 3224d0f..2648409 100644 --- a/src/Vecnavium/SkyBlocksPM/commands/subcommands/VisitSubCommand.php +++ b/src/Vecnavium/SkyBlocksPM/commands/subcommands/VisitSubCommand.php @@ -4,18 +4,19 @@ namespace Vecnavium\SkyBlocksPM\commands\subcommands; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\RawStringArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseSubCommand; -use Vecnavium\SkyBlocksPM\libs\jojoe77777\FormAPI\SimpleForm; -use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; -use Vecnavium\SkyBlocksPM\player\Player; +use CortexPE\Commando\args\RawStringArgument; +use CortexPE\Commando\BaseSubCommand; use pocketmine\command\CommandSender; use pocketmine\player\Player as P; use pocketmine\utils\Config; use pocketmine\utils\TextFormat; +use Vecnavium\SkyBlocksPM\libs\jojoe77777\FormAPI\SimpleForm; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; use Vecnavium\SkyBlocksPM\skyblock\SkyblockSettingTypes; use Vecnavium\SkyBlocksPM\SkyBlocksPM; use function in_array; +use function strval; class VisitSubCommand extends BaseSubCommand { @@ -24,6 +25,14 @@ protected function prepare(): void { $this->registerArgument(0, new RawStringArgument('name', true)); } + /** + * @param CommandSender $sender + * @param string $aliasUsed + * @param array $args + * @return void + * + * @phpstan-ignore-next-line + */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { /** @var SkyBlocksPM $plugin */ $plugin = $this->getOwningPlugin(); @@ -31,9 +40,9 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo if (!($sender instanceof P)) return; if (isset($args['name'])) { - $p = $plugin->getPlayerManager()->getPlayerByPrefix($args['name']); + $p = $plugin->getPlayerManager()->getPlayer(strval($args['name'])); if (!$p instanceof Player) { - $sender->sendMessage($plugin->getMessages()->getMessage('not-registered')); + $sender->sendMessage($plugin->getMessages()->getMessage('player-not-online')); return; } $skyblock = $plugin->getSkyBlockManager()->getSkyBlock($p->getSkyBlock()); @@ -45,31 +54,35 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $sender->sendMessage($plugin->getMessages()->getMessage('island-not-open')); return; } - $sender->teleport($plugin->getServer()->getWorldManager()->getWorldByName($skyblock->getWorld())->getSpawnLocation()); + $sender->teleport($skyblock->getSpawn()); } $skyblocks = []; foreach ($plugin->getServer()->getOnlinePlayers() as $player) { - $sbPlayer = $plugin->getPlayerManager()->getPlayerByPrefix($player->getName()); + $sbPlayer = $plugin->getPlayerManager()->getPlayer($player->getName()); if(!$sbPlayer instanceof Player) continue; $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($sbPlayer->getSkyBlock()); - if ($skyblock instanceof SkyBlock) - if(!in_array($skyblock->getUuid(), $skyblocks) && $skyblock->getSetting(SkyblockSettingTypes::SETTING_VISIT)) + if ($skyblock instanceof SkyBlock) { + if (!in_array($skyblock->getUuid(), $skyblocks, true) && $skyblock->getSetting(SkyblockSettingTypes::SETTING_VISIT)) { $skyblocks[] = $skyblock->getUuid(); + } + } } $form = new SimpleForm(function (P $player, ?int $data) use ($plugin, $skyblocks) { if($data === null) return; if (!isset($skyblocks[$data])) return; $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($skyblocks[$data]); - $player->teleport($plugin->getServer()->getWorldManager()->getWorldByName($skyblock->getWorld())->getSpawnLocation()); + if(!$skyblock instanceof SkyBlock) return; + $player->teleport($skyblock->getSpawn()); }); - $formConfig = new Config($plugin->getDataFolder() . "forms.yml", Config::YAML); - $form->setTitle(TextFormat::colorize($formConfig->getNested('visit.title'))); + $formConfig = new Config($plugin->getDataFolder() . 'forms.yml', Config::YAML); + $form->setTitle(TextFormat::colorize(strval($formConfig->getNested('visit.title')))); foreach ($skyblocks as $uuid) { $skyblock = $plugin->getSkyBlockManager()->getSkyBlockByUuid($uuid); - $form->addButton(TextFormat::colorize(str_replace('{NAME}', $skyblock->getLeader() , $formConfig->getNested('visit.buttons', '&l&a{NAME} SkyBlock')))); + if(!$skyblock instanceof SkyBlock) continue; + $form->addButton(TextFormat::colorize(str_replace('{NAME}', $skyblock->getLeader(), strval($formConfig->getNested('visit.buttons', '&l&a{NAME} SkyBlock'))))); } $sender->sendForm($form); } diff --git a/src/Vecnavium/SkyBlocksPM/config/Config.php b/src/Vecnavium/SkyBlocksPM/config/Config.php new file mode 100644 index 0000000..ee97924 --- /dev/null +++ b/src/Vecnavium/SkyBlocksPM/config/Config.php @@ -0,0 +1,18 @@ +getWorld(); + $defaultWorld = $this->plugin->getServer()->getWorldManager()->getDefaultWorld(); + if(!$defaultWorld instanceof World) return; + $world->setSpawnLocation($player->getPosition()); - $worldPath = $this->plugin->getServer()->getDataPath() . "worlds" . DIRECTORY_SEPARATOR . $world->getFolderName(); + $worldPath = $this->plugin->getServer()->getDataPath() . 'worlds' . DIRECTORY_SEPARATOR . $world->getFolderName(); - if ($world->getDisplayName() === $this->plugin->getServer()->getWorldManager()->getDefaultWorld()->getDisplayName()) { + if ($world->getDisplayName() === $defaultWorld->getDisplayName()) { $player->sendMessage($this->plugin->getMessages()->getMessage('default-world')); return; } - $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(realpath($worldPath)), RecursiveIteratorIterator::LEAVES_ONLY); + $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator((string)realpath($worldPath)), RecursiveIteratorIterator::LEAVES_ONLY); - $player->teleport($this->plugin->getServer()->getWorldManager()->getDefaultWorld()->getSpawnLocation()); + $player->teleport($defaultWorld->getSpawnLocation()); $this->plugin->getServer()->getWorldManager()->unloadWorld($world); /** @var SplFileInfo $file */ @@ -46,26 +51,26 @@ public function setIslandWorld(Player $player): void { $filePath = $file->getPath() . DIRECTORY_SEPARATOR . $file->getBasename(); $localPath = substr($filePath, strlen($this->plugin->getServer()->getDataPath() . 'worlds' . DIRECTORY_SEPARATOR . $world->getFolderName())); - @mkdir($this->plugin->getDataFolder() . "cache/island/db"); - copy($filePath, $this->plugin->getDataFolder() . "cache/island/" . $localPath); + @mkdir($this->plugin->getDataFolder() . 'cache/island/db'); + copy($filePath, $this->plugin->getDataFolder() . 'cache/island/' . $localPath); } } /** - * @param Player $player + * @param P $player * @param string $folderName * @param string $name * * Thanks SkyWars by GamakCZ */ - public function generateIsland(Player $player, string $folderName, string $name): void{ - $path = $this->plugin->getDataFolder() . "cache/island"; - $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(realpath($path)), RecursiveIteratorIterator::LEAVES_ONLY); + public function generateIsland(P $player, string $folderName, string $name): void{ + $path = $this->plugin->getDataFolder() . 'cache/island'; + $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator((string)realpath($path)), RecursiveIteratorIterator::LEAVES_ONLY); - $path = $this->plugin->getServer()->getDataPath() . "worlds" . DIRECTORY_SEPARATOR . $folderName; + $path = $this->plugin->getServer()->getDataPath() . 'worlds' . DIRECTORY_SEPARATOR . $folderName; @mkdir($path); - @mkdir($path . "/db"); + @mkdir($path . '/db'); /** @var SplFileInfo $file */ foreach ($files as $file) { @@ -80,8 +85,11 @@ public function generateIsland(Player $player, string $folderName, string $name) $this->plugin->getServer()->getWorldManager()->loadWorld($folderName); $world = $this->plugin->getServer()->getWorldManager()->getWorldByName($folderName); - $player->teleport(Position::fromObject($world->getSpawnLocation(), $world)); - $this->plugin->getSkyBlockManager()->createSkyBlock($world->getFolderName(), $this->plugin->getPlayerManager()->getPlayerByPrefix($player->getName()), $name, $world); + $skyBlockPlayer = $this->plugin->getPlayerManager()->getPlayer($player->getName()); + if($world instanceof World && $skyBlockPlayer instanceof Player) { + $player->teleport(Position::fromObject($world->getSpawnLocation(), $world)); + $this->plugin->getSkyBlockManager()->createSkyBlock($world->getFolderName(), $skyBlockPlayer, $name, $world); + } } } diff --git a/src/Vecnavium/SkyBlocksPM/invites/Invite.php b/src/Vecnavium/SkyBlocksPM/invites/Invite.php index 72dc55b..4296c82 100644 --- a/src/Vecnavium/SkyBlocksPM/invites/Invite.php +++ b/src/Vecnavium/SkyBlocksPM/invites/Invite.php @@ -4,47 +4,58 @@ namespace Vecnavium\SkyBlocksPM\invites; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; use pocketmine\player\Player; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class Invite { - private string $id; - private ?Player $inviter, $receiver; - - public function __construct(string $id, Player $inviter, Player $receiver) { - $this->id = $id; - $this->inviter = $inviter; - $this->receiver = $receiver; - } + public function __construct( + private string $id, + private Player $inviter, + private Player $receiver + ) {} + /** + * @return string + */ public function getId(): string { return $this->id; } - public function getInviter(): ?Player { + /** + * @return Player + */ + public function getInviter(): Player { return $this->inviter; } - public function getReceiver(): ?Player { + /** + * @return Player + */ + public function getReceiver(): Player { return $this->receiver; } public function cancel(): void { + /** @var Player[] $players */ $players = [$this->inviter, $this->receiver]; foreach ($players as $player) { - if ($player instanceof Player) + if ($player->isConnected()) { $player->sendMessage(SkyBlocksPM::getInstance()->getMessages()->getMessage('invite-expired')); + } } } + /** + * @return bool + */ public function handleInvite(): bool { - if (!$this->inviter instanceof Player) return false; + if (!$this->inviter->isConnected()) return false; - $inviter = SkyBlocksPM::getInstance()->getPlayerManager()->getPlayerByPrefix($this->inviter->getName()); - $receiver = SkyBlocksPM::getInstance()->getPlayerManager()->getPlayerByPrefix($this->receiver->getName()); + $inviter = SkyBlocksPM::getInstance()->getPlayerManager()->getPlayer($this->inviter->getName()); + $receiver = SkyBlocksPM::getInstance()->getPlayerManager()->getPlayer($this->receiver->getName()); - if ($inviter->getSkyBlock() == '' || $receiver->getSkyBlock() !== '') return false; + if ($inviter?->getSkyBlock() == '' || $receiver?->getSkyBlock() !== '') return false; return true; } diff --git a/src/Vecnavium/SkyBlocksPM/invites/InviteManager.php b/src/Vecnavium/SkyBlocksPM/invites/InviteManager.php index f3ea863..1e6df1e 100644 --- a/src/Vecnavium/SkyBlocksPM/invites/InviteManager.php +++ b/src/Vecnavium/SkyBlocksPM/invites/InviteManager.php @@ -15,6 +15,10 @@ public function addInvite(string $id, Player $inviter, Player $receiver): void { $this->invites[$id] = new Invite($id, $inviter, $receiver); } + /** + * @param string $name + * @return Invite|null + */ public function getPlayerInvites(string $name): ?Invite { foreach ($this->invites as $invite) { if ($invite->getInviter()->getName() == $name) return $invite; @@ -22,22 +26,30 @@ public function getPlayerInvites(string $name): ?Invite { return null; } + /** + * @param Player $player + * @return bool + */ public function canInvite(Player $player): bool { foreach ($this->invites as $invite) { - if ($invite->getInviter() instanceof Player) - if ($invite->getInviter()->getName() == $player->getName()) return false; + if ($invite->getInviter()->getName() == $player->getName()) return false; } return true; } - public function cancelInvite(string $id, bool $sendMessage = false) { + public function cancelInvite(string $id, bool $sendMessage = false): void{ if (!isset($this->invites[$id])) return; - if($sendMessage) + if($sendMessage) { $this->invites[$id]->cancel(); + } unset($this->invites[$id]); } - public function isInviteValid(string $id){ + /** + * @param string $id + * @return bool + */ + public function isInviteValid(string $id): bool{ return isset($this->invites[$id]); } } diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseCommand.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseCommand.php deleted file mode 100644 index dccb18e..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseCommand.php +++ /dev/null @@ -1,233 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\BaseArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint\BaseConstraint; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception\InvalidErrorCode; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits\ArgumentableTrait; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits\IArgumentable; -use pocketmine\command\Command; -use pocketmine\command\CommandSender; -use pocketmine\plugin\Plugin; -use pocketmine\plugin\PluginOwned; -use pocketmine\utils\TextFormat; -use function array_shift; -use function array_unique; -use function array_unshift; -use function count; -use function dechex; -use function implode; -use function str_replace; - -abstract class BaseCommand extends Command implements IArgumentable, IRunnable, PluginOwned { - use ArgumentableTrait; - - public const ERR_INVALID_ARG_VALUE = 0x01; - public const ERR_TOO_MANY_ARGUMENTS = 0x02; - public const ERR_INSUFFICIENT_ARGUMENTS = 0x03; - public const ERR_NO_ARGUMENTS = 0x04; - - /** @var string[] */ - protected $errorMessages = [ - self::ERR_INVALID_ARG_VALUE => TextFormat::RED . "Invalid value '{value}' for argument #{position}", - self::ERR_TOO_MANY_ARGUMENTS => TextFormat::RED . "Too many arguments given", - self::ERR_INSUFFICIENT_ARGUMENTS => TextFormat::RED . "Insufficient number of arguments given", - self::ERR_NO_ARGUMENTS => TextFormat::RED . "No arguments are required for this command", - ]; - - /** @var CommandSender */ - protected $currentSender; - - /** @var BaseSubCommand[] */ - private $subCommands = []; - - /** @var BaseConstraint[] */ - private $constraints = []; - - /** @var Plugin */ - private $plugin; - - public function __construct( - Plugin $plugin, - string $name, - string $description = "", - array $aliases = [] - ) { - $this->plugin = $plugin; - parent::__construct($name, $description, null, $aliases); - - $this->prepare(); - - $usages = ["/" . $this->generateUsageMessage()]; - foreach($this->subCommands as $subCommand) { - $usages[] = $subCommand->getUsageMessage(); - } - $usages = array_unique($usages); - $this->usageMessage = implode("\n - /" . $this->getName() . " ", $usages); - } - - public function getOwningPlugin(): Plugin { - return $this->plugin; - } - - final public function execute(CommandSender $sender, string $usedAlias, array $args) { - $this->currentSender = $sender; - if(!$this->testPermission($sender)) { - return; - } - /** @var BaseCommand|BaseSubCommand $cmd */ - $cmd = $this; - $passArgs = []; - if(count($args) > 0) { - if(isset($this->subCommands[($label = $args[0])])) { - array_shift($args); - $cmd = $this->subCommands[$label]; - $cmd->setCurrentSender($sender); - if(!$cmd->testPermissionSilent($sender)) { - $msg = $this->getPermissionMessage(); - if($msg === null) { - $sender->sendMessage( - $sender->getServer()->getLanguage()->translateString( - TextFormat::RED . "%commands.generic.permission" - ) - ); - } elseif(empty($msg)) { - $sender->sendMessage(str_replace("", $cmd->getPermission(), $msg)); - } - - return; - } - } - - $passArgs = $this->attemptArgumentParsing($cmd, $args); - } elseif($this->hasRequiredArguments()){ - $this->sendError(self::ERR_INSUFFICIENT_ARGUMENTS); - return; - } - if($passArgs !== null) { - foreach ($cmd->getConstraints() as $constraint){ - if(!$constraint->test($sender, $usedAlias, $passArgs)){ - $constraint->onFailure($sender, $usedAlias, $passArgs); - return; - } - } - $cmd->onRun($sender, $usedAlias, $passArgs); - } - } - - /** - * @param ArgumentableTrait $ctx - * @param array $args - * - * @return array|null - */ - private function attemptArgumentParsing($ctx, array $args): ?array { - $dat = $ctx->parseArguments($args, $this->currentSender); - if(!empty(($errors = $dat["errors"]))) { - foreach($errors as $error) { - $this->sendError($error["code"], $error["data"]); - } - - return null; - } - - return $dat["arguments"]; - } - - /** - * @param CommandSender $sender - * @param string $aliasUsed - * @param array|array> $args - */ - abstract public function onRun(CommandSender $sender, string $aliasUsed, array $args): void; - - protected function sendUsage(): void { - $this->currentSender->sendMessage("Usage: " . $this->getUsage()); - } - - public function sendError(int $errorCode, array $args = []): void { - $str = $this->errorMessages[$errorCode]; - foreach($args as $item => $value) { - $str = str_replace("{{$item}}", (string)$value, $str); - } - $this->currentSender->sendMessage($str); - } - - public function setErrorFormat(int $errorCode, string $format): void { - if(!isset($this->errorMessages[$errorCode])) { - throw new InvalidErrorCode("Invalid error code 0x" . dechex($errorCode)); - } - $this->errorMessages[$errorCode] = $format; - } - - public function setErrorFormats(array $errorFormats): void { - foreach($errorFormats as $errorCode => $format) { - $this->setErrorFormat($errorCode, $format); - } - } - - public function registerSubCommand(BaseSubCommand $subCommand): void { - $keys = $subCommand->getAliases(); - array_unshift($keys, $subCommand->getName()); - $keys = array_unique($keys); - foreach($keys as $key) { - if(!isset($this->subCommands[$key])) { - $subCommand->setParent($this); - $this->subCommands[$key] = $subCommand; - } else { - throw new \InvalidArgumentException("SubCommand with same name / alias for '{$key}' already exists"); - } - } - } - - /** - * @return BaseSubCommand[] - */ - public function getSubCommands(): array { - return $this->subCommands; - } - - public function addConstraint(BaseConstraint $constraint) : void { - $this->constraints[] = $constraint; - } - - /** - * @return BaseConstraint[] - */ - public function getConstraints(): array { - return $this->constraints; - } - - public function getUsageMessage(): string { - return $this->getUsage(); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseSubCommand.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseSubCommand.php deleted file mode 100644 index 7f0a25e..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/BaseSubCommand.php +++ /dev/null @@ -1,169 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint\BaseConstraint; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits\ArgumentableTrait; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits\IArgumentable; -use pocketmine\command\CommandSender; -use pocketmine\plugin\Plugin; -use function explode; - -abstract class BaseSubCommand implements IArgumentable, IRunnable { - use ArgumentableTrait; - /** @var string */ - private $name; - /** @var string[] */ - private $aliases = []; - /** @var string */ - private $description = ""; - /** @var string */ - protected $usageMessage; - /** @var string|null */ - private $permission = null; - /** @var CommandSender */ - protected $currentSender; - /** @var BaseCommand */ - protected $parent; - /** @var BaseConstraint[] */ - private $constraints = []; - - public function __construct(string $name, string $description = "", array $aliases = []) { - $this->name = $name; - $this->description = $description; - $this->aliases = $aliases; - - $this->prepare(); - - $this->usageMessage = $this->generateUsageMessage(); - } - - abstract public function onRun(CommandSender $sender, string $aliasUsed, array $args): void; - - /** - * @return string - */ - public function getName(): string { - return $this->name; - } - - /** - * @return string[] - */ - public function getAliases(): array { - return $this->aliases; - } - - /** - * @return string - */ - public function getDescription(): string { - return $this->description; - } - - /** - * @return string - */ - public function getUsageMessage(): string { - return $this->usageMessage; - } - - /** - * @return string|null - */ - public function getPermission(): ?string { - return $this->permission; - } - - /** - * @param string $permission - */ - public function setPermission(string $permission): void { - $this->permission = $permission; - } - - public function testPermissionSilent(CommandSender $sender): bool { - if(empty($this->permission)) { - return true; - } - foreach(explode(";", $this->permission) as $permission) { - if($sender->hasPermission($permission)) { - return true; - } - } - - return false; - } - - /** - * @param CommandSender $currentSender - * - * @internal Used to pass the current sender from the parent command - */ - public function setCurrentSender(CommandSender $currentSender): void { - $this->currentSender = $currentSender; - } - - /** - * @param BaseCommand $parent - * - * @internal Used to pass the parent context from the parent command - */ - public function setParent(BaseCommand $parent): void { - $this->parent = $parent; - } - - public function sendError(int $errorCode, array $args = []): void { - $this->parent->sendError($errorCode, $args); - } - - public function sendUsage():void { - $this->currentSender->sendMessage("/{$this->parent->getName()} {$this->usageMessage}"); - } - - public function addConstraint(BaseConstraint $constraint) : void { - $this->constraints[] = $constraint; - } - - /** - * @return BaseConstraint[] - */ - public function getConstraints(): array { - return $this->constraints; - } - - /** - * @return Plugin - */ - public function getOwningPlugin(): Plugin { - return $this->parent->getOwningPlugin(); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/IRunnable.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/IRunnable.php deleted file mode 100644 index 18038a9..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/IRunnable.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint\BaseConstraint; - -/** - * Interface IRunnable - * - * An interface which is declares the minimum required information - * to get background information for a command and/or a sub-command - * - * @package CortexPE\Commando - */ -interface IRunnable { - public function getName(): string; - - /** - * @return string[] - */ - public function getAliases(): array; - - public function getUsageMessage():string; - - public function getPermission(); // f*ck. PM didn't declare a return type... reeee - - /** - * @return BaseConstraint[] - */ - public function getConstraints():array; -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/PacketHooker.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/PacketHooker.php deleted file mode 100644 index c1ee55b..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/PacketHooker.php +++ /dev/null @@ -1,173 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception\HookAlreadyRegistered; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\store\SoftEnumStore; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits\IArgumentable; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\libs\muqsit\simplepackethandler\SimplePacketHandler; -use pocketmine\command\CommandMap; -use pocketmine\command\CommandSender; -use pocketmine\event\EventPriority; -use pocketmine\event\Listener; -use pocketmine\event\server\DataPacketSendEvent; -use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\types\command\CommandEnum; -use pocketmine\network\mcpe\protocol\types\command\CommandParameter; -use pocketmine\plugin\Plugin; -use pocketmine\Server; -use function array_unique; -use function array_unshift; -use function array_values; - -class PacketHooker implements Listener { - /** @var bool */ - private static $isRegistered = false; - /** @var bool */ - private static $isIntercepting = false; - - public static function isRegistered(): bool { - return self::$isRegistered; - } - - public static function register(Plugin $registrant): void { - if(self::$isRegistered) { - throw new HookAlreadyRegistered("Event listener is already registered by another plugin."); - } - - $interceptor = SimplePacketHandler::createInterceptor($registrant, EventPriority::NORMAL, false); - $interceptor->interceptOutgoing(function(AvailableCommandsPacket $pk, NetworkSession $target) : bool{ - if(self::$isIntercepting)return true; - $p = $target->getPlayer(); - foreach($pk->commandData as $commandName => $commandData) { - $cmd = Server::getInstance()->getCommandMap()->getCommand($commandName); - if($cmd instanceof BaseCommand) { - foreach($cmd->getConstraints() as $constraint){ - if(!$constraint->isVisibleTo($p)){ - continue 2; - } - } - $pk->commandData[$commandName]->overloads = self::generateOverloads($p, $cmd); - } - } - $pk->softEnums = SoftEnumStore::getEnums(); - self::$isIntercepting = true; - $target->sendDataPacket($pk); - self::$isIntercepting = false; - return false; - }); - } - - /** - * @param CommandSender $cs - * @param BaseCommand $command - * - * @return CommandParameter[][] - */ - private static function generateOverloads(CommandSender $cs, BaseCommand $command): array { - $overloads = []; - - foreach($command->getSubCommands() as $label => $subCommand) { - if(!$subCommand->testPermissionSilent($cs) || $subCommand->getName() !== $label){ // hide aliases - continue; - } - foreach($subCommand->getConstraints() as $constraint){ - if(!$constraint->isVisibleTo($cs)){ - continue 2; - } - } - $scParam = new CommandParameter(); - $scParam->paramName = $label; - $scParam->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_FLAG_ENUM; - $scParam->isOptional = false; - $scParam->enum = new CommandEnum($label, [$label]); - - $overloadList = self::generateOverloadList($subCommand); - if(!empty($overloadList)){ - foreach($overloadList as $overload) { - array_unshift($overload, $scParam); - $overloads[] = $overload; - } - } else { - $overloads[] = [$scParam]; - } - } - - foreach(self::generateOverloadList($command) as $overload) { - $overloads[] = $overload; - } - - return $overloads; - } - - /** - * @param IArgumentable $argumentable - * - * @return CommandParameter[][] - */ - private static function generateOverloadList(IArgumentable $argumentable): array { - $input = $argumentable->getArgumentList(); - $combinations = []; - $outputLength = array_product(array_map("count", $input)); - $indexes = []; - foreach($input as $k => $charList){ - $indexes[$k] = 0; - } - do { - /** @var CommandParameter[] $set */ - $set = []; - foreach($indexes as $k => $index){ - $param = $set[$k] = clone $input[$k][$index]->getNetworkParameterData(); - - if(isset($param->enum) && $param->enum instanceof CommandEnum){ - $refClass = new \ReflectionClass(CommandEnum::class); - $refProp = $refClass->getProperty("enumName"); - $refProp->setAccessible(true); - $refProp->setValue($param->enum, "enum#" . spl_object_id($param->enum)); - } - } - $combinations[] = $set; - - foreach($indexes as $k => $v){ - $indexes[$k]++; - $lim = count($input[$k]); - if($indexes[$k] >= $lim){ - $indexes[$k] = 0; - continue; - } - break; - } - } while(count($combinations) !== $outputLength); - - return $combinations; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BaseArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BaseArgument.php deleted file mode 100644 index d10b6ea..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BaseArgument.php +++ /dev/null @@ -1,103 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\types\command\CommandParameter; - -abstract class BaseArgument { - /** @var string */ - protected $name; - /** @var bool */ - protected $optional = false; - /** @var CommandParameter */ - protected $parameterData; - - public function __construct(string $name, bool $optional = false) { - $this->name = $name; - $this->optional = $optional; - - $this->parameterData = new CommandParameter(); - $this->parameterData->paramName = $name; - $this->parameterData->paramType = AvailableCommandsPacket::ARG_FLAG_VALID; - $this->parameterData->paramType |= $this->getNetworkType(); - $this->parameterData->isOptional = $this->isOptional(); - } - - abstract public function getNetworkType(): int; - - /** - * @param string $testString - * @param CommandSender $sender - * - * @return bool - */ - abstract public function canParse(string $testString, CommandSender $sender): bool; - - /** - * @param string $argument - * @param CommandSender $sender - * - * @return mixed - */ - abstract public function parse(string $argument, CommandSender $sender); - - /** - * @return string - */ - public function getName(): string { - return $this->name; - } - - /** - * @return bool - */ - public function isOptional(): bool { - return $this->optional; - } - - /** - * Returns how much command arguments - * it takes to build the full argument - * - * @return int - */ - public function getSpanLength(): int { - return 1; - } - - abstract public function getTypeName(): string; - - public function getNetworkParameterData():CommandParameter { - return $this->parameterData; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BlockPositionArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BlockPositionArgument.php deleted file mode 100644 index 3580efa..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BlockPositionArgument.php +++ /dev/null @@ -1,48 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\math\Vector3; -use function preg_match; - -class BlockPositionArgument extends Vector3Argument { - public function isValidCoordinate(string $coordinate, bool $locatable): bool { - return (bool)preg_match("/^(?:" . ($locatable ? "(?:~-|~\+)?" : "") . "-?\d+)" . ($locatable ? "|~" : "") . "$/", $coordinate); - } - - public function parse(string $argument, CommandSender $sender) { - /** @var Vector3 $v */ - $v = parent::parse($argument, $sender); - - return $v->floor(); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BooleanArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BooleanArgument.php deleted file mode 100644 index 15c628b..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/BooleanArgument.php +++ /dev/null @@ -1,48 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; - -class BooleanArgument extends StringEnumArgument { - protected const VALUES = [ - "true" => true, - "false" => false, - ]; - - public function getTypeName(): string { - return "bool"; - } - - public function parse(string $argument, CommandSender $sender) { - return $this->getValue($argument); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/FloatArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/FloatArgument.php deleted file mode 100644 index eb7f5a8..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/FloatArgument.php +++ /dev/null @@ -1,53 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use function preg_match; - -class FloatArgument extends BaseArgument { - public function getNetworkType(): int { - return AvailableCommandsPacket::ARG_TYPE_FLOAT; - } - - public function getTypeName(): string { - return "decimal"; - } - - public function canParse(string $testString, CommandSender $sender): bool { - return (bool)preg_match("/^-?(?:\d+|\d*\.\d+)$/", $testString); - } - - public function parse(string $argument, CommandSender $sender) { - return (float)$argument; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/IntegerArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/IntegerArgument.php deleted file mode 100644 index 1fcf4bf..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/IntegerArgument.php +++ /dev/null @@ -1,53 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use function preg_match; - -class IntegerArgument extends BaseArgument { - public function getNetworkType(): int { - return AvailableCommandsPacket::ARG_TYPE_INT; - } - - public function getTypeName(): string { - return "int"; - } - - public function canParse(string $testString, CommandSender $sender): bool { - return (bool)preg_match("/^-?(?:\d+)$/", $testString); - } - - public function parse(string $argument, CommandSender $sender) { - return (int)$argument; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/RawStringArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/RawStringArgument.php deleted file mode 100644 index 615e89a..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/RawStringArgument.php +++ /dev/null @@ -1,51 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; - -class RawStringArgument extends BaseArgument { - public function getNetworkType(): int { - return AvailableCommandsPacket::ARG_TYPE_STRING; - } - - public function getTypeName(): string { - return "string"; - } - - public function canParse(string $testString, CommandSender $sender): bool { - return true; - } - - public function parse(string $argument, CommandSender $sender) { - return $argument; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/StringEnumArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/StringEnumArgument.php deleted file mode 100644 index b83a359..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/StringEnumArgument.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\types\command\CommandEnum; -use function array_keys; -use function array_map; -use function implode; -use function preg_match; -use function spl_object_hash; -use function strtolower; - -abstract class StringEnumArgument extends BaseArgument { - protected const VALUES = []; - - public function __construct(string $name, bool $optional = false) { - parent::__construct($name, $optional); - - $this->parameterData->enum = new CommandEnum("", $this->getEnumValues()); - } - - public function getNetworkType(): int { - // this will be disregarded by PM anyways because this will be considered as a string enum - return -1; - } - - public function canParse(string $testString, CommandSender $sender): bool { - return (bool)preg_match( - "/^(" . implode("|", array_map("\\strtolower", $this->getEnumValues())) . ")$/iu", - $testString - ); - } - - public function getValue(string $string) { - return static::VALUES[strtolower($string)]; - } - - public function getEnumValues(): array { - return array_keys(static::VALUES); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/TextArgument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/TextArgument.php deleted file mode 100644 index 44e9ccb..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/TextArgument.php +++ /dev/null @@ -1,51 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; - -class TextArgument extends RawStringArgument { - public function getNetworkType(): int { - return AvailableCommandsPacket::ARG_TYPE_RAWTEXT; - } - - public function getTypeName(): string { - return "text"; - } - - public function getSpanLength(): int { - return PHP_INT_MAX; - } - public function canParse(string $testString, CommandSender $sender): bool { - return $testString !== ""; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/Vector3Argument.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/Vector3Argument.php deleted file mode 100644 index 4dc127f..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/args/Vector3Argument.php +++ /dev/null @@ -1,100 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args; - - -use pocketmine\command\CommandSender; -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use function count; -use function explode; -use function preg_match; -use function substr; - -class Vector3Argument extends BaseArgument { - public function getNetworkType(): int { - return AvailableCommandsPacket::ARG_TYPE_POSITION; - } - - public function getTypeName(): string { - return "x y z"; - } - - public function canParse(string $testString, CommandSender $sender): bool { - $coords = explode(" ", $testString); - if(count($coords) === 3) { - foreach($coords as $coord) { - if(!$this->isValidCoordinate($coord, $sender instanceof Vector3)) { - return false; - } - } - - return true; - } - - return false; - } - - public function isValidCoordinate(string $coordinate, bool $locatable): bool { - return (bool)preg_match("/^(?:" . ($locatable ? "(?:~-|~\+)?" : "") . "-?(?:\d+|\d*\.\d+))" . ($locatable ? "|~" : "") . "$/", $coordinate); - } - - public function parse(string $argument, CommandSender $sender) { - $coords = explode(" ", $argument); - $vals = []; - foreach($coords as $k => $coord){ - $offset = 0; - // if it's locatable and starts with ~- or ~+ - if($sender instanceof Vector3 && preg_match("/^(?:~-|~\+)|~/", $coord)){ - // this will work with -n, +n and "" due to typecast later - $offset = substr($coord, 1); - - // replace base coordinate with actual entity coordinates - switch($k){ - case 0: - $coord = $sender->x; - break; - case 1: - $coord = $sender->y; - break; - case 2: - $coord = $sender->z; - break; - } - } - $vals[] = (float)$coord + (float)$offset; - } - return new Vector3(...$vals); - } - - public function getSpanLength(): int { - return 3; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/BaseConstraint.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/BaseConstraint.php deleted file mode 100644 index d2c8b7f..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/BaseConstraint.php +++ /dev/null @@ -1,63 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\IRunnable; -use pocketmine\command\CommandSender; - -abstract class BaseConstraint { - /** @var IRunnable */ - protected $context; - - /** - * BaseConstraint constructor. - * - * "Context" is required so that this new-constraint-system doesn't hinder getting command info - * - * @param IRunnable $context - */ - public function __construct(IRunnable $context) { - $this->context = $context; - } - - /** - * @return IRunnable - */ - public function getContext(): IRunnable { - return $this->context; - } - - abstract public function test(CommandSender $sender, string $aliasUsed, array $args): bool; - - abstract public function onFailure(CommandSender $sender, string $aliasUsed, array $args): void; - - abstract public function isVisibleTo(CommandSender $sender): bool; -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/ConsoleRequiredConstraint.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/ConsoleRequiredConstraint.php deleted file mode 100644 index 4f4a696..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/ConsoleRequiredConstraint.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint; - - -use pocketmine\command\CommandSender; -use pocketmine\player\Player; -use pocketmine\utils\TextFormat; - -class ConsoleRequiredConstraint extends BaseConstraint { - - public function test(CommandSender $sender, string $aliasUsed, array $args): bool { - return $this->isVisibleTo($sender); - } - - public function onFailure(CommandSender $sender, string $aliasUsed, array $args): void { - $sender->sendMessage(TextFormat::RED . "This command must be executed from a server console."); // f*ck off grammar police - } - - public function isVisibleTo(CommandSender $sender): bool { - return !($sender instanceof Player); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/InGameRequiredConstraint.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/InGameRequiredConstraint.php deleted file mode 100644 index c739589..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/constraint/InGameRequiredConstraint.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\constraint; - - -use pocketmine\command\CommandSender; -use pocketmine\player\Player; -use pocketmine\utils\TextFormat; - -class InGameRequiredConstraint extends BaseConstraint { - - public function test(CommandSender $sender, string $aliasUsed, array $args): bool { - return $this->isVisibleTo($sender); - } - - public function onFailure(CommandSender $sender, string $aliasUsed, array $args): void { - $sender->sendMessage(TextFormat::RED . "This command must be executed in-game."); // f*ck off grammar police - } - - public function isVisibleTo(CommandSender $sender): bool { - return $sender instanceof Player; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/ArgumentOrderException.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/ArgumentOrderException.php deleted file mode 100644 index 551e800..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/ArgumentOrderException.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception; - - -class ArgumentOrderException extends CommandoException { - -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/CommandoException.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/CommandoException.php deleted file mode 100644 index b85a3ed..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/CommandoException.php +++ /dev/null @@ -1,37 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception; - - -use Exception; - -class CommandoException extends Exception { - -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/HookAlreadyRegistered.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/HookAlreadyRegistered.php deleted file mode 100644 index 148b3ed..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/HookAlreadyRegistered.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception; - - -class HookAlreadyRegistered extends CommandoException { - -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/InvalidErrorCode.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/InvalidErrorCode.php deleted file mode 100644 index dbb84a6..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/exception/InvalidErrorCode.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception; - - -class InvalidErrorCode extends CommandoException { - -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/SimplePacketHandler.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/SimplePacketHandler.php deleted file mode 100644 index d45e1a0..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/SimplePacketHandler.php +++ /dev/null @@ -1,27 +0,0 @@ -listener = new PacketInterceptorListener($register, $priority, $handleCancelled); - } - - public function interceptIncoming(Closure $handler) : IPacketInterceptor{ - $this->listener->interceptIncoming($handler); - return $this; - } - - public function interceptOutgoing(Closure $handler) : IPacketInterceptor{ - $this->listener->interceptOutgoing($handler); - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php deleted file mode 100644 index ba8b80a..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php +++ /dev/null @@ -1,116 +0,0 @@ -> - */ - private array $incoming_handlers = []; - - /** - * @var Closure[][] - * @phpstan-var array> - */ - private array $outgoing_handlers = []; - - public function __construct(Plugin $register, int $priority, bool $handleCancelled){ - $this->register = $register; - $this->priority = $priority; - $this->handleCancelled = $handleCancelled; - } - - public function interceptIncoming(Closure $handler) : IPacketInterceptor{ - $classes = ClosureSignatureParser::parse($handler, [ServerboundPacket::class, NetworkSession::class], "bool"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->incoming_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->incoming_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, $this->incoming_event_handler = function(DataPacketReceiveEvent $event) : void{ - /** @var DataPacket|ServerboundPacket $packet */ - $packet = $event->getPacket(); - if(isset($this->incoming_handlers[$pid = $packet::NETWORK_ID])){ - $origin = $event->getOrigin(); - foreach($this->incoming_handlers[$pid] as $handler){ - if(!$handler($packet, $origin)){ - $event->cancel(); - break; - } - } - } - }, $this->priority, $this->register, $this->handleCancelled); - } - - return $this; - } - - public function interceptOutgoing(Closure $handler) : IPacketInterceptor{ - $classes = ClosureSignatureParser::parse($handler, [ClientboundPacket::class, NetworkSession::class], "bool"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->outgoing_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->outgoing_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, $this->outgoing_event_handler = function(DataPacketSendEvent $event) : void{ - $original_targets = $event->getTargets(); - $packets = $event->getPackets(); - - /** @var DataPacket|ClientboundPacket $packet */ - foreach($packets as $packet){ - if(isset($this->outgoing_handlers[$pid = $packet::NETWORK_ID])){ - $remaining_targets = $original_targets; - - foreach($remaining_targets as $i => $target){ - foreach($this->outgoing_handlers[$pid] as $handler){ - if(!$handler($packet, $target)){ - unset($remaining_targets[$i]); - break; - } - } - } - - $remaining_targets_c = count($remaining_targets); - if($remaining_targets_c !== count($original_targets)){ - $event->cancel(); - if($remaining_targets_c > 0){ - $new_target_players = []; - foreach($remaining_targets as $new_target){ - $new_target_player = $new_target->getPlayer(); - if($new_target_player !== null){ - $new_target_players[] = $new_target_player; - } - } - - Server::getInstance()->broadcastPackets($new_target_players, $packets); - } - break; - } - } - } - }, $this->priority, $this->register, $this->handleCancelled); - } - - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php deleted file mode 100644 index f9e3456..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php +++ /dev/null @@ -1,31 +0,0 @@ -listener = new PacketMonitorListener($register, $handleCancelled); - } - - public function monitorIncoming(Closure $handler) : IPacketMonitor{ - $this->listener->monitorIncoming($handler); - return $this; - } - - public function monitorOutgoing(Closure $handler) : IPacketMonitor{ - $this->listener->monitorOutgoing($handler); - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php deleted file mode 100644 index 54b3742..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php +++ /dev/null @@ -1,87 +0,0 @@ -> - */ - private array $incoming_handlers = []; - - /** - * @var Closure[][] - * @phpstan-var array> - */ - private array $outgoing_handlers = []; - - public function __construct(Plugin $register, bool $handleCancelled){ - $this->register = $register; - $this->handleCancelled = $handleCancelled; - } - - public function monitorIncoming(Closure $handler) : IPacketMonitor{ - $classes = ClosureSignatureParser::parse($handler, [ServerboundPacket::class, NetworkSession::class], "void"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->incoming_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->incoming_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, $this->incoming_event_handler = function(DataPacketReceiveEvent $event) : void{ - /** @var DataPacket|ServerboundPacket $packet */ - $packet = $event->getPacket(); - if(isset($this->incoming_handlers[$pid = $packet::NETWORK_ID])){ - $origin = $event->getOrigin(); - foreach($this->incoming_handlers[$pid] as $handler){ - $handler($packet, $origin); - } - } - }, EventPriority::MONITOR, $this->register, $this->handleCancelled); - } - - return $this; - } - - public function monitorOutgoing(Closure $handler) : IPacketMonitor{ - $classes = ClosureSignatureParser::parse($handler, [ClientboundPacket::class, NetworkSession::class], "void"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->outgoing_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->outgoing_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, $this->outgoing_event_handler = function(DataPacketSendEvent $event) : void{ - /** @var DataPacket|ClientboundPacket $packet */ - foreach($event->getPackets() as $packet){ - if(isset($this->outgoing_handlers[$pid = $packet::NETWORK_ID])){ - foreach($event->getTargets() as $target){ - foreach($this->outgoing_handlers[$pid] as $handler){ - $handler($packet, $target); - } - } - } - } - }, EventPriority::MONITOR, $this->register, $this->handleCancelled); - } - - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php deleted file mode 100644 index 94caef7..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php +++ /dev/null @@ -1,49 +0,0 @@ -getReturnType(); - if(!($type instanceof ReflectionNamedType) || $type->allowsNull() || $type->getName() !== $return_type){ - throw new InvalidArgumentException("Return value of {$method->getName()} must be {$return_type}"); - } - - $parsed_params = []; - $parameters = $method->getParameters(); - if(count($parameters) === count($params)){ - $parameter_index = 0; - foreach($parameters as $parameter){ - $parameter_type = $parameter->getType(); - $parameter_compare = $params[$parameter_index++]; - if($parameter_type instanceof ReflectionNamedType && !$parameter_type->allowsNull() && is_a($parameter_type->getName(), $parameter_compare, true)){ - $parsed_params[] = $parameter_type->getName(); - continue; - } - break; - } - - if(count($parsed_params) === count($params)){ - return $parsed_params; - } - } - - throw new InvalidArgumentException("Closure must satisfy signature (" . implode(", ", $params) . ") : {$return_type}"); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/store/SoftEnumStore.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/store/SoftEnumStore.php deleted file mode 100644 index 5477ae5..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/store/SoftEnumStore.php +++ /dev/null @@ -1,60 +0,0 @@ -getName()] = $enum; - self::broadcastSoftEnum($enum, UpdateSoftEnumPacket::TYPE_ADD); - } - - public static function updateEnum(string $enumName, array $values):void { - if(self::getEnumByName($enumName) === null){ - throw new CommandoException("Unknown enum named " . $enumName); - } - self::$enums[$enum->getName()] = $enum = new CommandEnum($enumName, $values); - self::broadcastSoftEnum($enum, UpdateSoftEnumPacket::TYPE_SET); - } - - public static function removeEnum(string $enumName):void { - if(($enum = self::getEnumByName($enumName)) === null){ - throw new CommandoException("Unknown enum named " . $enumName); - } - unset(static::$enums[$enumName]); - self::broadcastSoftEnum($enum, UpdateSoftEnumPacket::TYPE_REMOVE); - } - - public static function broadcastSoftEnum(CommandEnum $enum, int $type):void { - $pk = new UpdateSoftEnumPacket(); - $pk->enumName = $enum->getName(); - $pk->values = $enum->getValues(); - $pk->type = $type; - self::broadcastPacket($pk); - } - - private static function broadcastPacket(ClientboundPacket $pk):void { - ($sv = Server::getInstance())->broadcastPackets($sv->getOnlinePlayers(), [$pk]); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/ArgumentableTrait.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/ArgumentableTrait.php deleted file mode 100644 index 8cc44e7..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/ArgumentableTrait.php +++ /dev/null @@ -1,210 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\BaseArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\TextArgument; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\BaseCommand; -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\exception\ArgumentOrderException; -use pocketmine\command\CommandSender; -use function array_slice; -use function count; -use function implode; -use function is_array; -use function usort; - -trait ArgumentableTrait { - /** @var BaseArgument[][] */ - private $argumentList = []; // [argumentPosition => [...possible BaseArgument(s)]] - /** @var bool[] */ - private $requiredArgumentCount = []; - - /** - * This is where all the arguments, permissions, sub-commands, etc would be registered - */ - abstract protected function prepare(): void; - - /** - * @param int $position - * @param BaseArgument $argument - * - * @throws ArgumentOrderException - */ - public function registerArgument(int $position, BaseArgument $argument): void { - if($position < 0) { - throw new ArgumentOrderException("You cannot register arguments at negative positions"); - } - if($position > 0 && !isset($this->argumentList[$position - 1])) { - throw new ArgumentOrderException("There were no arguments before $position"); - } - foreach($this->argumentList[$position - 1] ?? [] as $arg) { - if($arg instanceof TextArgument) { - throw new ArgumentOrderException("No other arguments can be registered after a TextArgument"); - } - if($arg->isOptional() && !$argument->isOptional()){ - throw new ArgumentOrderException("You cannot register a required argument after an optional argument"); - } - } - $this->argumentList[$position][] = $argument; - if(!$argument->isOptional()) { - $this->requiredArgumentCount[$position] = true; - } - } - - public function parseArguments(array $rawArgs, CommandSender $sender): array { - $return = [ - "arguments" => [], - "errors" => [] - ]; - // try parsing arguments - $required = count($this->requiredArgumentCount); - if(!$this->hasArguments() && count($rawArgs) > 0) { // doesnt take args but sender gives args anyways - $return["errors"][] = [ - "code" => BaseCommand::ERR_NO_ARGUMENTS, - "data" => [] - ]; - } - $offset = 0; - if(count($rawArgs) > 0) { - foreach($this->argumentList as $pos => $possibleArguments) { - // try the one that spans more first... before the others - usort($possibleArguments, function (BaseArgument $a, BaseArgument $b): int { - if($a->getSpanLength() === PHP_INT_MAX) { // if it takes unlimited arguments, pull it down - return 1; - } - - return -1; - }); - $parsed = false; - $optional = true; - foreach($possibleArguments as $argument) { - $arg = trim(implode(" ", array_slice($rawArgs, $offset, ($len = $argument->getSpanLength())))); - if(!$argument->isOptional()) { - $optional = false; - } - if($arg !== "" && $argument->canParse($arg, $sender)) { - $k = $argument->getName(); - $result = (clone $argument)->parse($arg, $sender); - if(isset($return["arguments"][$k]) && !is_array($return["arguments"][$k])) { - $old = $return["arguments"][$k]; - unset($return["arguments"][$k]); - $return["arguments"][$k] = [$old]; - $return["arguments"][$k][] = $result; - } else { - $return["arguments"][$k] = $result; - } - if(!$optional) { - $required--; - } - $offset += $len; - $parsed = true; - break; - } - if($offset > count($rawArgs)) { - break; // we've reached the end of the argument list the user passed - } - } - if(!$parsed && !($optional && empty($arg))) { // we tried every other possible argument type, none was satisfied - $return["errors"][] = [ - "code" => BaseCommand::ERR_INVALID_ARG_VALUE, - "data" => [ - "value" => $rawArgs[$offset] ?? "", - "position" => $pos + 1 - ] - ]; - - return $return; // let's break it here. - } - } - } - if($offset < count($rawArgs)) { // this means that the arguments our user sent is more than the needed amount - $return["errors"][] = [ - "code" => BaseCommand::ERR_TOO_MANY_ARGUMENTS, - "data" => [] - ]; - } - if($required > 0) {// We still have more unfilled required arguments - $return["errors"][] = [ - "code" => BaseCommand::ERR_INSUFFICIENT_ARGUMENTS, - "data" => [] - ]; - } - - return $return; - } - - public function generateUsageMessage(): string { - $msg = $this->getName() . " "; - $args = []; - foreach($this->argumentList as $pos => $arguments) { - $hasOptional = false; - $names = []; - foreach($arguments as $k => $argument) { - $names[] = $argument->getName() . ":" . $argument->getTypeName(); - if($argument->isOptional()) { - $hasOptional = true; - } - } - $names = implode("|", $names); - if($hasOptional) { - $args[] = "[" . $names . "]"; - } else { - $args[] = "<" . $names . ">"; - } - } - $msg .= implode(" ", $args); - - return $msg; - } - - public function hasArguments(): bool { - return !empty($this->argumentList); - } - - public function hasRequiredArguments(): bool { - foreach($this->argumentList as $arguments) { - foreach($arguments as $argument) { - if(!$argument->isOptional()) { - return true; - } - } - } - - return false; - } - - /** - * @return BaseArgument[][] - */ - public function getArgumentList(): array { - return $this->argumentList; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/IArgumentable.php b/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/IArgumentable.php deleted file mode 100644 index 70280cb..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/CortexPE/Commando/traits/IArgumentable.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - * Written by @CortexPE - * - */ -declare(strict_types=1); - -namespace Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\traits; - - -use Vecnavium\SkyBlocksPM\libs\CortexPE\Commando\args\BaseArgument; -use pocketmine\command\CommandSender; - -interface IArgumentable { - public function generateUsageMessage(): string; - public function hasArguments(): bool; - - /** - * @return BaseArgument[][] - */ - public function getArgumentList(): array; - public function parseArguments(array $rawArgs, CommandSender $sender): array; - public function registerArgument(int $position, BaseArgument $argument): void; -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/CustomForm.php b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/CustomForm.php index b7d2d10..9a938e4 100644 --- a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/CustomForm.php +++ b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/CustomForm.php @@ -4,7 +4,6 @@ namespace Vecnavium\SkyBlocksPM\libs\jojoe77777\FormAPI; -use jojoe77777\FormAPI\Form; use pocketmine\form\FormValidationException; use function count; use function gettype; @@ -131,7 +130,7 @@ public function addStepSlider(string $text, array $steps, int $defaultIndex = -1 /** * @param string $text * @param array $options - * @param int $default + * @param int|null $default * @param string|null $label */ public function addDropdown(string $text, array $options, int $default = null, ?string $label = null) : void { @@ -143,7 +142,7 @@ public function addDropdown(string $text, array $options, int $default = null, ? /** * @param string $text * @param string $placeholder - * @param string $default + * @param string|null $default * @param string|null $label */ public function addInput(string $text, string $placeholder = "", string $default = null, ?string $label = null) : void { diff --git a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/Form.php b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/Form.php index ef76d97..970cd5e 100644 --- a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/Form.php +++ b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/Form.php @@ -49,7 +49,7 @@ public function handleResponse(Player $player, $data) : void { public function processData(&$data) : void { } - public function jsonSerialize(){ + public function jsonSerialize() : array{ return $this->data; } } diff --git a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/SimpleForm.php b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/SimpleForm.php index c9cad50..baf8d68 100644 --- a/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/SimpleForm.php +++ b/src/Vecnavium/SkyBlocksPM/libs/jojoe77777/FormAPI/SimpleForm.php @@ -4,7 +4,6 @@ namespace Vecnavium\SkyBlocksPM\libs\jojoe77777\FormAPI; -use jojoe77777\FormAPI\Form; use pocketmine\form\FormValidationException; use function count; use function gettype; @@ -15,10 +14,8 @@ class SimpleForm extends Form { const IMAGE_TYPE_PATH = 0; const IMAGE_TYPE_URL = 1; - /** @var string */ - private $content = ""; - - private $labelMap = []; + private string $content = ""; + private array $labelMap = []; /** * @param callable|null $callable @@ -76,7 +73,7 @@ public function setContent(string $content) : void { * @param string $text * @param int $imageType * @param string $imagePath - * @param string $label + * @param string|null $label */ public function addButton(string $text, int $imageType = -1, string $imagePath = "", ?string $label = null) : void { $content = ["text" => $text]; diff --git a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/SimplePacketHandler.php b/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/SimplePacketHandler.php deleted file mode 100644 index 04ef775..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/SimplePacketHandler.php +++ /dev/null @@ -1,27 +0,0 @@ -listener = new PacketInterceptorListener($register, $priority, $handleCancelled); - } - - public function interceptIncoming(Closure $handler) : IPacketInterceptor{ - $this->listener->interceptIncoming($handler); - return $this; - } - - public function interceptOutgoing(Closure $handler) : IPacketInterceptor{ - $this->listener->interceptOutgoing($handler); - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php b/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php deleted file mode 100644 index ad1a3e8..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/interceptor/PacketInterceptorListener.php +++ /dev/null @@ -1,113 +0,0 @@ -> - */ - private array $incoming_handlers = []; - - /** - * @var Closure[][] - * @phpstan-var array> - */ - private array $outgoing_handlers = []; - - public function __construct( - private Plugin $register, - private int $priority, - private bool $handleCancelled - ){} - - public function interceptIncoming(Closure $handler) : IPacketInterceptor{ - $classes = ClosureSignatureParser::parse($handler, [ServerboundPacket::class, NetworkSession::class], "bool"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->incoming_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->incoming_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, $this->incoming_event_handler = function(DataPacketReceiveEvent $event) : void{ - /** @var DataPacket&ServerboundPacket $packet */ - $packet = $event->getPacket(); - if(isset($this->incoming_handlers[$pid = $packet::NETWORK_ID])){ - $origin = $event->getOrigin(); - foreach($this->incoming_handlers[$pid] as $handler){ - if(!$handler($packet, $origin)){ - $event->cancel(); - break; - } - } - } - }, $this->priority, $this->register, $this->handleCancelled); - } - - return $this; - } - - public function interceptOutgoing(Closure $handler) : IPacketInterceptor{ - $classes = ClosureSignatureParser::parse($handler, [ClientboundPacket::class, NetworkSession::class], "bool"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->outgoing_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->outgoing_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, $this->outgoing_event_handler = function(DataPacketSendEvent $event) : void{ - $original_targets = $event->getTargets(); - $packets = $event->getPackets(); - - /** @var DataPacket&ClientboundPacket $packet */ - foreach($packets as $packet){ - if(isset($this->outgoing_handlers[$pid = $packet::NETWORK_ID])){ - $remaining_targets = $original_targets; - - foreach($remaining_targets as $i => $target){ - foreach($this->outgoing_handlers[$pid] as $handler){ - if(!$handler($packet, $target)){ - unset($remaining_targets[$i]); - break; - } - } - } - - $remaining_targets_c = count($remaining_targets); - if($remaining_targets_c !== count($original_targets)){ - $event->cancel(); - if($remaining_targets_c > 0){ - $new_target_players = []; - foreach($remaining_targets as $new_target){ - $new_target_player = $new_target->getPlayer(); - if($new_target_player !== null){ - $new_target_players[] = $new_target_player; - } - } - - Server::getInstance()->broadcastPackets($new_target_players, $packets); - } - break; - } - } - } - }, $this->priority, $this->register, $this->handleCancelled); - } - - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php b/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php deleted file mode 100644 index 5329c8f..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/IPacketMonitor.php +++ /dev/null @@ -1,31 +0,0 @@ -listener = new PacketMonitorListener($register, $handleCancelled); - } - - public function monitorIncoming(Closure $handler) : IPacketMonitor{ - $this->listener->monitorIncoming($handler); - return $this; - } - - public function monitorOutgoing(Closure $handler) : IPacketMonitor{ - $this->listener->monitorOutgoing($handler); - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php b/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php deleted file mode 100644 index d8b550c..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/monitor/PacketMonitorListener.php +++ /dev/null @@ -1,85 +0,0 @@ -> - */ - private array $incoming_handlers = []; - - /** - * @var Closure[][] - * @phpstan-var array> - */ - private array $outgoing_handlers = []; - - public function __construct( - private Plugin $register, - private bool $handleCancelled - ){} - - public function monitorIncoming(Closure $handler) : IPacketMonitor{ - $classes = ClosureSignatureParser::parse($handler, [ServerboundPacket::class, NetworkSession::class], "void"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->incoming_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->incoming_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, $this->incoming_event_handler = function(DataPacketReceiveEvent $event) : void{ - /** @var DataPacket&ServerboundPacket $packet */ - $packet = $event->getPacket(); - if(isset($this->incoming_handlers[$pid = $packet::NETWORK_ID])){ - $origin = $event->getOrigin(); - foreach($this->incoming_handlers[$pid] as $handler){ - $handler($packet, $origin); - } - } - }, EventPriority::MONITOR, $this->register, $this->handleCancelled); - } - - return $this; - } - - public function monitorOutgoing(Closure $handler) : IPacketMonitor{ - $classes = ClosureSignatureParser::parse($handler, [ClientboundPacket::class, NetworkSession::class], "void"); - assert(is_a($classes[0], DataPacket::class, true)); - $this->outgoing_handlers[$classes[0]::NETWORK_ID][spl_object_id($handler)] = $handler; - - if($this->outgoing_event_handler === null){ - Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, $this->outgoing_event_handler = function(DataPacketSendEvent $event) : void{ - /** @var DataPacket&ClientboundPacket $packet */ - foreach($event->getPackets() as $packet){ - if(isset($this->outgoing_handlers[$pid = $packet::NETWORK_ID])){ - foreach($event->getTargets() as $target){ - foreach($this->outgoing_handlers[$pid] as $handler){ - $handler($packet, $target); - } - } - } - } - }, EventPriority::MONITOR, $this->register, $this->handleCancelled); - } - - return $this; - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php b/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php deleted file mode 100644 index cf68df1..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/muqsit/simplepackethandler/utils/ClosureSignatureParser.php +++ /dev/null @@ -1,49 +0,0 @@ -getReturnType(); - if(!($type instanceof ReflectionNamedType) || $type->allowsNull() || $type->getName() !== $return_type){ - throw new InvalidArgumentException("Return value of {$method->getName()} must be {$return_type}"); - } - - $parsed_params = []; - $parameters = $method->getParameters(); - if(count($parameters) === count($params)){ - $parameter_index = 0; - foreach($parameters as $parameter){ - $parameter_type = $parameter->getType(); - $parameter_compare = $params[$parameter_index++]; - if($parameter_type instanceof ReflectionNamedType && !$parameter_type->allowsNull() && is_a($parameter_type->getName(), $parameter_compare, true)){ - $parsed_params[] = $parameter_type->getName(); - continue; - } - break; - } - - if(count($parsed_params) === count($params)){ - return $parsed_params; - } - } - - throw new InvalidArgumentException("Closure must satisfy signature (" . implode(", ", $params) . ") : {$return_type}"); - } -} \ No newline at end of file diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ConfigException.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ConfigException.php deleted file mode 100644 index 789e94f..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ConfigException.php +++ /dev/null @@ -1,31 +0,0 @@ -feof(), fgets() and fclose(). - * @param string|null $fileName the filename providing the stream, only used for debugging and documentation purposes - * - * @throws GenericStatementFileParseException if the file contains a syntax error or compile error - * @throws InvalidArgumentException if the file introduces statements that duplicate the names of those previously loaded - */ - public function loadQueryFile($fh, string $fileName = null) : void; - - /** - * Loads a pre-formatted query. - * - * @param GenericStatement $stmt - * - * @throws InvalidArgumentException if the statement duplicates the name of one previously loaded - */ - public function loadQuery(GenericStatement $stmt) : void; - - /** - * Executes a generic query that either succeeds or fails. - * - * @param string $queryName the {@link GenericPreparedStatement} query name - * @param mixed[] $args the variables as defined in the {@link GenericPreparedStatement} - * @param callable|null $onSuccess an optional callback when the query has succeeded: function() : void{} - * @param callable|null $onError an optional callback when the query has failed: function({@link SqlError} $error) : void{} - */ - public function executeGeneric(string $queryName, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void; - - public function executeGenericRaw(string $query, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void; - - /** - * Executes a query that changes data. - * - * @param string $queryName the {@link GenericPreparedStatement} query name - * @param mixed[] $args the variables as defined in the {@link GenericPreparedStatement} - * @param callable|null $onSuccess an optional callback when the query has succeeded: function(int $affectedRows) : void{} - * @param callable|null $onError an optional callback when the query has failed: function({@link SqlError} $error) : void{} - */ - public function executeChange(string $queryName, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void; - - public function executeChangeRaw(string $query, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void; - - /** - * Executes an insert query that results in an insert ID. - * - * @param string $queryName the {@link GenericPreparedStatement} query name - * @param mixed[] $args the variables as defined in the {@link GenericPreparedStatement} - * @param callable|null $onInserted an optional callback when the query has succeeded: function(int $insertId, int $affectedRows) : void{} - * @param callable|null $onError an optional callback when the query has failed: function({@link SqlError} $error) : void{} - */ - public function executeInsert(string $queryName, array $args = [], ?callable $onInserted = null, ?callable $onError = null) : void; - - public function executeInsertRaw(string $query, array $args = [], ?callable $onInserted = null, ?callable $onError = null) : void; - - /** - * Executes a select query that returns an SQL result set. This does not strictly need to be SELECT queries -- reflection queries like MySQL's SHOW TABLES query are also allowed. - * - * @param string $queryName the {@link GenericPreparedStatement} query name - * @param mixed[] $args the variables as defined in the {@link GenericPreparedStatement} - * @param callable|null $onSelect an optional callback when the query has succeeded: function(array[] $rows, SqlColumnInfo[] $columns) : void{} - * @param callable|null $onError an optional callback when the query has failed: function({@link SqlError} $error) : void{} - */ - public function executeSelect(string $queryName, array $args = [], ?callable $onSelect = null, ?callable $onError = null) : void; - - public function executeSelectRaw(string $query, array $args = [], ?callable $onSelect = null, ?callable $onError = null) : void; - - /** - * This function waits all pending queries to complete then returns. This is as if the queries were executed in blocking mode (not async). - * - * This method should only under very rare events like server start/stop. This should not be run trivially (e.g. every time player joins), because otherwise this is not async. - */ - public function waitAll() : void; - - /** - * Closes the connection and/or all child connections. Remember to call this method when the plugin is disabled or the data provider is switched. - */ - public function close() : void; -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ExtensionMissingException.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ExtensionMissingException.php deleted file mode 100644 index afe7203..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/ExtensionMissingException.php +++ /dev/null @@ -1,47 +0,0 @@ - $line){ - if(strpos($line, ";extension=") !== false && stripos($line, $extensionName) !== false){ - $instructions = TextFormat::GOLD . "Please remove the leading semicolon on line " . ($i + 1) . " of $ini and restart the server " . TextFormat::RED . "so that the $extensionName extension can be loaded."; - } - } - } - - parent::__construct("The $extensionName extension is missing. $instructions"); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/GenericStatement.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/GenericStatement.php deleted file mode 100644 index 0d0493c..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/GenericStatement.php +++ /dev/null @@ -1,66 +0,0 @@ -stage = $stage; - $this->errorMessage = $errorMessage; - $this->query = $query; - $this->args = $args; - - parent::__construct("SQL $stage error: $errorMessage" . ($query === null ? "" : (", for query $query | " . json_encode($args)))); - $this->flattenTrace(); - } - - /** - * Returns the stage of query execution at which the error occurred. - * - * @return string - */ - public function getStage() : string{ - return $this->stage; - } - - /** - * Returns the error message - * - * @return string - */ - public function getErrorMessage() : string{ - return $this->errorMessage; - } - - /** - * Returns the original query - * - * @return string|null - */ - public function getQuery() : ?string{ - return $this->query; - } - - /** - * Returns the original arguments passed to the query - * - * @return mixed[]|null - */ - public function getArgs() : ?array{ - return $this->args; - } - - /** - * Flattens the trace such that the exception can be serialized - * - * @see https://gist.github.com/Thinkscape/805ba8b91cdce6bcaf7c Exception flattening solution by Artur Bodera - */ - protected function flattenTrace() : void{ - $traceProperty = (new ReflectionClass(Exception::class))->getProperty('trace'); - $traceProperty->setAccessible(true); - $flatten = static function(&$value){ - if($value instanceof Closure){ - $closureReflection = new ReflectionFunction($value); - $value = sprintf( - '(Closure at %s:%s)', - $closureReflection->getFileName(), - $closureReflection->getStartLine() - ); - }elseif(is_object($value)){ - $value = sprintf('object(%s)', get_class($value)); - }elseif(is_resource($value)){ - $value = sprintf('resource(%s)', get_resource_type($value)); - } - }; - do{ - $trace = $traceProperty->getValue($this); - foreach($trace as &$call){ - array_walk_recursive($call['args'], $flatten); - } - unset($call); - $traceProperty->setValue($this, $trace); - }while($exception = $this->getPrevious()); - $traceProperty->setAccessible(false); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/SqlResult.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/SqlResult.php deleted file mode 100644 index e5bcb4d..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/SqlResult.php +++ /dev/null @@ -1,27 +0,0 @@ -"?" for mysqli-based backends, null for PDO-based and SQLite3-based backends. - * @param bool $logQueries - */ - public function __construct(Plugin $plugin, SqlThread $thread, ?string $placeHolder, bool $logQueries = false){ - $this->plugin = $plugin; - if($thread instanceof SqlThreadPool){ - $thread->setDataConnector($this); - } - $this->thread = $thread; - $this->logger = $logQueries ? $plugin->getLogger() : null; - $this->placeHolder = $placeHolder; - } - - public function setLoggingQueries(bool $loggingQueries) : void{ - $this->logger = $loggingQueries ? $this->plugin->getLogger() : null; - } - - public function isLoggingQueries() : bool{ - return $this->logger !== null; - } - - public function getLogger() : ?PluginLogger{ - return $this->logger; - } - - public function setLogger(?PluginLogger $logger) : void{ - $this->logger = $logger; - } - - public function loadQueryFile($fh, string $fileName = null) : void{ - if(!is_resource($fh)){ - throw new TypeError("Missing $fileName in resources directory of plugin."); - } - - $parser = new GenericStatementFileParser($fileName, $fh); - $parser->parse(); - foreach($parser->getResults() as $result){ - $this->loadQuery($result); - } - } - - public function loadQuery(GenericStatement $stmt) : void{ - if(isset($this->queries[$stmt->getName()])){ - throw new InvalidArgumentException("Duplicate GenericStatement: {$stmt->getName()}"); - } - $this->queries[$stmt->getName()] = $stmt; - } - - public function executeGeneric(string $queryName, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void{ - $this->executeImpl($queryName, $args, SqlThread::MODE_GENERIC, static function() use ($onSuccess){ - if($onSuccess !== null){ - $onSuccess(); - } - }, $onError); - } - - public function executeGenericRaw(string $query, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void{ - $this->executeImplRaw($query, $args, SqlThread::MODE_GENERIC, static function() use ($onSuccess){ - if($onSuccess !== null){ - $onSuccess(); - } - }, $onError); - } - - public function executeChange(string $queryName, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void{ - $this->executeImpl($queryName, $args, SqlThread::MODE_CHANGE, static function(SqlChangeResult $result) use ($onSuccess){ - if($onSuccess !== null){ - $onSuccess($result->getAffectedRows()); - } - }, $onError); - } - - public function executeChangeRaw(string $query, array $args = [], ?callable $onSuccess = null, ?callable $onError = null) : void{ - $this->executeImplRaw($query, $args, SqlThread::MODE_CHANGE, static function(SqlChangeResult $result) use ($onSuccess){ - if($onSuccess !== null){ - $onSuccess($result->getAffectedRows()); - } - }, $onError); - } - - public function executeInsert(string $queryName, array $args = [], ?callable $onInserted = null, ?callable $onError = null) : void{ - $this->executeImpl($queryName, $args, SqlThread::MODE_INSERT, static function(SqlInsertResult $result) use ($onInserted){ - if($onInserted !== null){ - $onInserted($result->getInsertId(), $result->getAffectedRows()); - } - }, $onError); - } - - public function executeInsertRaw(string $query, array $args = [], ?callable $onInserted = null, ?callable $onError = null) : void{ - $this->executeImplRaw($query, $args, SqlThread::MODE_INSERT, static function(SqlInsertResult $result) use ($onInserted){ - if($onInserted !== null){ - $onInserted($result->getInsertId(), $result->getAffectedRows()); - } - }, $onError); - } - - public function executeSelect(string $queryName, array $args = [], ?callable $onSelect = null, ?callable $onError = null) : void{ - $this->executeImpl($queryName, $args, SqlThread::MODE_SELECT, static function(SqlSelectResult $result) use ($onSelect){ - if($onSelect !== null){ - $onSelect($result->getRows(), $result->getColumnInfo()); - } - }, $onError); - } - - public function executeSelectRaw(string $query, array $args = [], ?callable $onSelect = null, ?callable $onError = null) : void{ - $this->executeImplRaw($query, $args, SqlThread::MODE_SELECT, static function(SqlSelectResult $result) use ($onSelect){ - if($onSelect !== null){ - $onSelect($result->getRows(), $result->getColumnInfo()); - } - }, $onError); - } - - private function executeImpl(string $queryName, array $args, int $mode, callable $handler, ?callable $onError) : void{ - if(!isset($this->queries[$queryName])){ - throw new InvalidArgumentException("The query $queryName has not been loaded"); - } - $query = $this->queries[$queryName]->format($args, $this->placeHolder, $outArgs); - - $this->executeImplRaw($query, $outArgs, $mode, $handler, $onError); - } - - private function executeImplRaw(string $query, array $args, int $mode, callable $handler, ?callable $onError) : void{ - $queryId = $this->queryId++; - $trace = libasynql::isPackaged() ? null : new Exception("(This is the original stack trace for the following error)"); - $this->handlers[$queryId] = function($result) use ($handler, $onError, $trace){ - if($result instanceof SqlError){ - $this->reportError($onError, $result, $trace); - }else{ - try{ - $handler($result); - }catch(Exception $e){ - if(!libasynql::isPackaged()){ - $prop = (new ReflectionClass(Exception::class))->getProperty("trace"); - $prop->setAccessible(true); - $newTrace = $prop->getValue($e); - $oldTrace = $prop->getValue($trace); - for($i = count($newTrace) - 1, $j = count($oldTrace) - 1; $i >= 0 && $j >= 0 && $newTrace[$i] === $oldTrace[$j]; --$i, --$j){ - array_pop($newTrace); - } - /** @noinspection PhpUndefinedMethodInspection */ - $prop->setValue($e, array_merge($newTrace, [ - [ - "function" => Terminal::$COLOR_YELLOW . "--- below is the original stack trace ---" . Terminal::$FORMAT_RESET, - ], - ], $oldTrace)); - } - throw $e; - }catch(Error $e){ - if(!libasynql::isPackaged()){ - $exceptionProperty = (new ReflectionClass(Exception::class))->getProperty("trace"); - $exceptionProperty->setAccessible(true); - $oldTrace = $exceptionProperty->getValue($trace); - - $errorProperty = (new ReflectionClass(Error::class))->getProperty("trace"); - $errorProperty->setAccessible(true); - $newTrace = $errorProperty->getValue($e); - - for($i = count($newTrace) - 1, $j = count($oldTrace) - 1; $i >= 0 && $j >= 0 && $newTrace[$i] === $oldTrace[$j]; --$i, --$j){ - array_pop($newTrace); - } - /** @noinspection PhpUndefinedMethodInspection */ - $errorProperty->setValue($e, array_merge($newTrace, [ - [ - "function" => Terminal::$COLOR_YELLOW . "--- below is the original stack trace ---" . Terminal::$FORMAT_RESET, - ], - ], $oldTrace)); - } - throw $e; - } - } - }; - if($this->logger !== null){ - $this->logger->debug("Queuing mode-$mode query: " . str_replace(["\r\n", "\n"], "\\n ", $query) . " | Args: " . json_encode($args)); - } - $this->thread->addQuery($queryId, $mode, $query, $args); - } - - private function reportError(?callable $default, SqlError $error, ?Exception $trace) : void{ - if($default !== null){ - try{ - $default($error, $trace); - $error = null; - }catch(SqlError $err){ - $error = $err; - } - } - if($error !== null){ - $this->plugin->getLogger()->error($error->getMessage()); - if($error->getQuery() !== null){ - $this->plugin->getLogger()->debug("Query: " . $error->getQuery()); - } - if($error->getArgs() !== null){ - $this->plugin->getLogger()->debug("Args: " . json_encode($error->getArgs())); - } - if($trace !== null){ - $this->plugin->getLogger()->debug("Stack trace: " . $trace->getTraceAsString()); - } - } - } - - public function waitAll() : void{ - while(!empty($this->handlers)){ - $this->checkResults(); - usleep(1000); - } - } - - public function checkResults() : void{ - $this->thread->readResults($this->handlers); - } - - public function close() : void{ - $this->thread->stopRunning(); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueryRecvQueue.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueryRecvQueue.php deleted file mode 100644 index 554a6d1..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueryRecvQueue.php +++ /dev/null @@ -1,49 +0,0 @@ -shift(); - if(is_string($row)){ - [$queryId, $result] = unserialize($row, ["allowed_classes" => true]); - return true; - } - return false; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QuerySendQueue.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QuerySendQueue.php deleted file mode 100644 index 03630c9..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QuerySendQueue.php +++ /dev/null @@ -1,70 +0,0 @@ -queries = new Threaded(); - } - - public function scheduleQuery(int $queryId, int $mode, string $query, array $params) : void{ - if($this->invalidated){ - throw new QueueShutdownException("You cannot schedule a query on an invalidated queue."); - } - $this->synchronized(function() use ($queryId, $mode, $query, $params) : void{ - $this->queries[] = serialize([$queryId, $mode, $query, $params]); - $this->notifyOne(); - }); - } - - public function fetchQuery() : ?string { - return $this->synchronized(function(): ?string { - while($this->queries->count() === 0 && !$this->isInvalidated()){ - $this->wait(); - } - return $this->queries->shift(); - }); - } - - public function invalidate() : void { - $this->synchronized(function():void{ - $this->invalidated = true; - $this->notify(); - }); - } - - /** - * @return bool - */ - public function isInvalidated(): bool { - return $this->invalidated; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueueShutdownException.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueueShutdownException.php deleted file mode 100644 index 8fad48a..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/QueueShutdownException.php +++ /dev/null @@ -1,30 +0,0 @@ -notifier = $notifier; - - $this->slaveNumber = self::$nextSlaveNumber++; - $this->bufferSend = $bufferSend ?? new QuerySendQueue(); - $this->bufferRecv = $bufferRecv ?? new QueryRecvQueue(); - - if(!libasynql::isPackaged()){ - /** @noinspection PhpUndefinedMethodInspection */ - /** @noinspection NullPointerExceptionInspection */ - /** @var ClassLoader $cl */ - $cl = Server::getInstance()->getPluginManager()->getPlugin("DEVirion")->getVirionClassLoader(); - $this->setClassLoaders([Server::getInstance()->getLoader(), $cl]); - } - $this->start(PTHREADS_INHERIT_INI | PTHREADS_INHERIT_CONSTANTS); - } - - protected function onRun() : void{ - $error = $this->createConn($resource); - $this->connCreated = true; - $this->connError = $error; - - if($error !== null){ - return; - } - - while(true){ - $row = $this->bufferSend->fetchQuery(); - if(!is_string($row)){ - break; - } - $this->busy = true; - [$queryId, $mode, $query, $params] = unserialize($row, ["allowed_classes" => true]); - try{ - $result = $this->executeQuery($resource, $mode, $query, $params); - $this->bufferRecv->publishResult($queryId, $result); - }catch(SqlError $error){ - $this->bufferRecv->publishError($queryId, $error); - } - $this->notifier->wakeupSleeper(); - $this->busy = false; - } - $this->close($resource); - } - - /** - * @return bool - */ - public function isBusy(): bool { - return $this->busy; - } - - public function stopRunning() : void{ - $this->bufferSend->invalidate(); - - parent::quit(); - } - - public function quit() : void{ - $this->stopRunning(); - parent::quit(); - } - - public function addQuery(int $queryId, int $mode, string $query, array $params) : void{ - $this->bufferSend->scheduleQuery($queryId, $mode, $query, $params); - } - - public function readResults(array &$callbacks) : void{ - while($this->bufferRecv->fetchResult($queryId, $result)){ - if(!isset($callbacks[$queryId])){ - throw new InvalidArgumentException("Missing handler for query #$queryId"); - } - - $callbacks[$queryId]($result); - unset($callbacks[$queryId]); - } - } - - public function connCreated() : bool{ - return $this->connCreated; - } - - public function hasConnError() : bool{ - return $this->connError !== null; - } - - public function getConnError() : ?string{ - return $this->connError; - } - - protected abstract function createConn(&$resource) : ?string; - - /** - * @param mixed $resource - * @param int $mode - * @param string $query - * @param mixed[] $params - * - * @return SqlResult - * @throws SqlError - */ - protected abstract function executeQuery($resource, int $mode, string $query, array $params) : SqlResult; - - - protected abstract function close(&$resource) : void; -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/SqlThreadPool.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/SqlThreadPool.php deleted file mode 100644 index dc4ef4f..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/base/SqlThreadPool.php +++ /dev/null @@ -1,132 +0,0 @@ -dataConnector = $dataConnector; - } - - /** - * SqlThreadPool constructor. - * - * @param callable $workerFactory create a child worker: function(?Threaded $bufferSend = null, ?Threaded $bufferRecv = null) : {@link BaseSqlThread}{} - * @param int $workerLimit the maximum number of workers to create. Workers are created lazily. - */ - public function __construct(callable $workerFactory, int $workerLimit){ - $this->notifier = new SleeperNotifier(); - Server::getInstance()->getTickSleeper()->addNotifier($this->notifier, function() : void{ - assert($this->dataConnector instanceof DataConnectorImpl); // otherwise, wtf - $this->dataConnector->checkResults(); - }); - - $this->workerFactory = $workerFactory; - $this->workerLimit = $workerLimit; - $this->bufferSend = new QuerySendQueue(); - $this->bufferRecv = new QueryRecvQueue(); - - $this->addWorker(); - } - - private function addWorker() : void{ - $this->workers[] = ($this->workerFactory)($this->notifier, $this->bufferSend, $this->bufferRecv); - } - - public function join() : void{ - foreach($this->workers as $worker){ - $worker->join(); - } - } - - public function stopRunning() : void{ - foreach($this->workers as $worker){ - $worker->stopRunning(); - } - } - - public function addQuery(int $queryId, int $mode, string $query, array $params) : void{ - $this->bufferSend->scheduleQuery($queryId, $mode, $query, $params); - - // check if we need to increase worker size - foreach($this->workers as $worker){ - if(!$worker->isBusy()){ - return; - } - } - if(count($this->workers) < $this->workerLimit){ - $this->addWorker(); - } - } - - public function readResults(array &$callbacks) : void{ - while($this->bufferRecv->fetchResult($queryId, $result)){ - if(!isset($callbacks[$queryId])){ - throw new InvalidArgumentException("Missing handler for query #$queryId"); - } - - $callbacks[$queryId]($result); - unset($callbacks[$queryId]); - } - } - - public function connCreated() : bool{ - return $this->workers[0]->connCreated(); - } - - public function hasConnError() : bool{ - return $this->workers[0]->hasConnError(); - } - - public function getConnError() : ?string{ - return $this->workers[0]->getConnError(); - } - - public function getLoad() : float{ - return $this->bufferSend->count() / (float) $this->workerLimit; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParseException.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParseException.php deleted file mode 100644 index d1996e7..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParseException.php +++ /dev/null @@ -1,51 +0,0 @@ -problem = $problem; - $this->lineNo = $lineNo; - $this->queryFile = $file ?? "SQL file"; - - parent::__construct("Error parsing prepared statement file: $problem on line $lineNo in $file"); - } - - public function getProblem() : string{ - return $this->problem; - } - - public function getLineNo() : int{ - return $this->lineNo; - } - - public function getQueryFile() : string{ - return $this->queryFile; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParser.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParser.php deleted file mode 100644 index 2ab8bdc..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementFileParser.php +++ /dev/null @@ -1,253 +0,0 @@ -fileName = $fileName; - $this->fh = $fh; - } - - /** - * Parses the file, and closes the stream. - * - * @throws GenericStatementFileParseException if the file contains a syntax error or compile error - */ - public function parse() : void{ - try{ - while(($line = fgets($this->fh)) !== false){ - $this->readLine($this->lineNo + 1, $line); - } - if(!empty($this->identifierStack)){ - $this->error("Unexpected end of file, " . count($this->identifierStack) . " groups not closed"); - } - }finally{ - fclose($this->fh); - } - } - - /** - * @return GenericStatement[] - */ - public function getResults() : array{ - return $this->results; - } - - private function readLine(int $lineNo, string $line) : void{ - $this->lineNo = $lineNo; // In fact I don't need this parameter. I just want to get the line number onto the stack trace. - $line = trim($line); - - if($line === ""){ - return; - } - - if($this->tryCommand($line)){ - return; - } - - if(empty($this->identifierStack)){ - $this->error("Unexpected query text; start a query with { first"); - } - $this->buffer[] = $line; - $this->parsingQuery = true; - } - - private function tryCommand(string $line) : bool{ - if(strpos($line, "-- #") !== 0){ - return false; - } - - $line = ltrim(substr($line, 4)); - if($line === ''){ - return true; - } - $cmd = $line[0]; - $args = []; - $argOffsets = []; - $regex = /** @lang RegExp */ - '/[ \t]/'; - foreach(preg_split($regex, substr($line, 1), -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE) as [$arg, $offset]){ - $args[] = $arg; - $argOffsets[] = $offset; - } - - switch($cmd){ - case "!": - $this->dialectCommand($args); - return true; - case "{": - $this->startCommand($args); - return true; - case "}": - $this->endCommand(); - return true; - case "*": - $this->docCommand($args, $line, $argOffsets); - return true; - case ":": - $this->varCommand($args, $line, $argOffsets); - return true; - } - - return true; - } - - private function dialectCommand(array $args) : void{ - // dialect command - if($this->knownDialect !== null){ - $this->error("Dialect declared more than once"); - } - - if(!isset($args[0])){ - $this->error("Missing operand: DIALECT"); - } - - $this->knownDialect = $args[0]; - } - - private function startCommand(array $args) : void{ - if($this->knownDialect === null){ - $this->error("Dialect declaration must be the very first line"); - } - - if($this->parsingQuery){ - $this->error("Unexpected {, close previous query first"); - } - - if(!isset($args[0])){ - $this->error("Missing operand: IDENTIFIER_NAME"); - } - - $this->identifierStack[] = $args[0]; - } - - private function endCommand() : void{ - if(count($this->identifierStack) === 0){ - $this->error("No matching { for }"); - } - - if($this->parsingQuery){ - if(count($this->buffer) === 0){ - $this->error("Documentation/Variables are declared but no query is provided"); - } - - $query = implode("\n", $this->buffer); - $doc = implode("\n", $this->docLines); // double line breaks => single line breaks - assert($this->knownDialect !== null); - $stmt = GenericStatementImpl::forDialect($this->knownDialect, implode(".", $this->identifierStack), $query, $doc, $this->variables, $this->fileName, $this->lineNo); - $this->docLines = []; - $this->variables = []; - $this->buffer = []; - $this->parsingQuery = false; - - if(isset($this->results[$stmt->getName()])){ - $this->error("Duplicate query name ({$stmt->getName()})"); - } - $this->results[$stmt->getName()] = $stmt; - } // end query - - array_pop($this->identifierStack); - } - - private function varCommand(array $args, string $line, array $argOffsets) : void{ - if(empty($this->identifierStack)){ - $this->error("Unexpected variable declaration; start a query with { first"); - } - - if(!isset($args[1])){ - $this->error("Missing operand: VAR_TYPE"); - } - - try{ - $var = new GenericVariable($args[0], $args[1], isset($args[2]) ? substr($line, $argOffsets[2] + 1) : null); - }catch(InvalidArgumentException $e){ - throw $this->error($e->getMessage()); - } - if(isset($this->variables[$var->getName()])){ - $this->error("Duplicate variable definition of :{$var->getName()}"); - } - $this->variables[$var->getName()] = $var; - $this->parsingQuery = true; - } - - private function docCommand(array $args, string $line, array $argOffsets) : void{ - if(empty($this->identifierStack)){ - $this->error("Unexpected documentation; start a query with { first"); - } - - $this->docLines[] = trim(substr($line, 1)); - $this->parsingQuery = true; - } - - /** - * @param string $problem - * @return GenericStatementFileParseException - * @throw GenericStatementFileParseException - */ - private function error(string $problem) : GenericStatementFileParseException{ - throw new GenericStatementFileParseException($problem, $this->lineNo, $this->fileName); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementImpl.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementImpl.php deleted file mode 100644 index de31cbc..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericStatementImpl.php +++ /dev/null @@ -1,218 +0,0 @@ -name; - } - - public function getQuery() : string{ - return $this->query; - } - - public function getDoc() : string{ - return $this->doc; - } - - public function getVariables() : array{ - return $this->variables; - } - - public function getFile() : ?string{ - return $this->file; - } - - public function getLineNumber() : int{ - return $this->lineNo; - } - - /** - * @param string $dialect - * @param string $name - * @param string $query - * @param string $doc - * @param GenericVariable[] $variables - * @param string|null $file - * @param int $lineNo - * @return GenericStatementImpl - */ - public static function forDialect(string $dialect, string $name, string $query, string $doc, array $variables, ?string $file, int $lineNo) : GenericStatementImpl{ - static $classMap = [ - SqlDialect::MYSQL => MysqlStatementImpl::class, - SqlDialect::SQLITE => SqliteStatementImpl::class, - ]; - $className = $classMap[$dialect]; - return new $className($name, $query, $doc, $variables, $file, $lineNo); - } - - public function __construct(string $name, string $query, string $doc, array $variables, ?string $file, int $lineNo){ - $this->name = $name; - $this->query = $query; - $this->doc = $doc; - $this->variables = $variables; - $this->file = $file !== null ? str_replace("\\", "/", $file) : null; - $this->lineNo = $lineNo; - - $this->compilePositions(); - } - - protected function compilePositions() : void{ - uksort($this->variables, static function($s1, $s2){ - return mb_strlen($s2) <=> mb_strlen($s1); - }); - - $usedNames = []; - - $positions = []; - $quotesState = null; - for($i = 1, $iMax = mb_strlen($this->query); $i < $iMax; ++$i){ - $thisChar = mb_substr($this->query, $i, 1); - - if($quotesState !== null){ - if($thisChar === "\\"){ - ++$i; // skip one character - continue; - } - if($thisChar === $quotesState){ - $quotesState = null; - continue; - } - continue; - } - if(in_array($thisChar, ["'", "\"", "`"], true)){ - $quotesState = $thisChar; - continue; - } - - if($thisChar === ":"){ - $name = null; - - foreach($this->variables as $variable){ - if(mb_strpos($this->query, $variable->getName(), $i + 1) === $i + 1){ - $positions[$i] = $name = $variable->getName(); - break; - // if multiple variables match, the first one i.e. the longest one wins - } - } - - if($name !== null){ - $usedNames[$name] = true; - $i += mb_strlen($name); // skip the name - } - } - } - - $newQuery = ""; - $lastPos = 0; - foreach($positions as $pos => $name){ - $newQuery .= mb_substr($this->query, $lastPos, $pos - $lastPos); - $this->varPositions[mb_strlen($newQuery)] = $name; // we aren't using $pos here, because we want the position in the cleaned string, not the position in the original query string - $lastPos = $pos + mb_strlen($name) + 1; - } - $newQuery .= mb_substr($this->query, $lastPos); - - $this->query = $newQuery; - - foreach($this->variables as $variable){ - if(!isset($usedNames[$variable->getName()])){ - throw new InvalidArgumentException("The variable {$variable->getName()} is not used anywhere in the query! Check for typos."); - } - } - } - - public function format(array $vars, ?string $placeHolder, ?array &$outArgs) : string{ - $outArgs = []; - foreach($this->variables as $variable){ - if(!$variable->isOptional() && !array_key_exists($variable->getName(), $vars)){ - throw new InvalidArgumentException("Missing required variable {$variable->getName()}"); - } - } - - $query = ""; - - $lastPos = 0; - foreach($this->varPositions as $pos => $name){ - $query .= mb_substr($this->query, $lastPos, $pos - $lastPos); - $value = $vars[$name] ?? $this->variables[$name]->getDefault(); - try{ - $query .= $this->formatVariable($this->variables[$name], $value, $placeHolder, $outArgs); - }catch(AssertionError $e){ - throw new InvalidArgumentException("Invalid value for :$name - " . $e->getMessage() . ", " . self::getType($value) . " given", 0, $e); - } - $lastPos = $pos; - } - $query .= mb_substr($this->query, $lastPos); - - return $query; - } - - private static function getType($value){ - return is_object($value) ? get_class($value) : gettype($value); - } - - protected abstract function formatVariable(GenericVariable $variable, $value, ?string $placeHolder, array &$outArgs) : string; - - public function jsonSerialize(){ - return [ - "name" => $this->name, - "query" => $this->query, - "doc" => $this->doc, - "variables" => $this->variables, - "file" => $this->file, - "lineNo" => $this->lineNo, - ]; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericVariable.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericVariable.php deleted file mode 100644 index 1134eaa..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/GenericVariable.php +++ /dev/null @@ -1,205 +0,0 @@ -name = $name; - if(stripos($type, "list:") === 0){ - $this->list = true; - /** @noinspection CallableParameterUseCaseInTypeContextInspection */ - $type = substr($type, strlen("list:")); - }elseif(stripos($type, "list?") === 0){ - $this->list = true; - $this->canEmpty = true; - /** @noinspection CallableParameterUseCaseInTypeContextInspection */ - $type = substr($type, strlen("list?")); - }elseif($type[0] === "?"){ - $this->nullable = true; - $type = substr($type, 1); - } - $this->type = $type; - if($default !== null){ - if($this->list){ - throw new InvalidArgumentException("Lists cannot have default value"); - } - switch($type){ - case self::TYPE_STRING: - if($default[0] === "\"" && $default[strlen($default) - 1] === "\""){ - $default = json_decode($default); - assert(is_string($default)); - } - $this->default = $default; - break; - - case self::TYPE_INT: - $this->default = (int) $default; - break; - - case self::TYPE_FLOAT: - $this->default = (float) $default; - break; - - case self::TYPE_BOOL: - $this->default = in_array($default, ["true", "on", "1"], true); - break; - - case self::TYPE_TIMESTAMP: - if(!in_array(strtoupper($default), [ - self::TIME_NOW, - self::TIME_0, - ], true)){ - throw new InvalidArgumentException("Invalid timestamp default"); - } - $this->default = $default; - break; - - default: - throw new InvalidArgumentException("Unknown type \"$type\""); - } - } - } - - public function unlist() : GenericVariable{ - if(!$this->list){ - throw new InvalidStateException("Cannot unlist a non-list variable"); - } - $clone = clone $this; - $clone->list = false; - return $clone; - } - - public function getName() : string{ - return $this->name; - } - - public function isList() : bool{ - return $this->list; - } - - /** - * Returns whether the list variable is declared with list? rather than list:. - * - * If the SQL dialect does not support empty list declarations (), and list: is used, an exception will be thrown when an empty array is passed as the value. If list? is used, a randomly-generated string will be filled into the array to satisfy the language's requirements. This might cause undesired behaviour unless you are only using this variable for a simple IN :list condition. - * - * As this may expose a security breach or a performance degrade, plugins are not encouraged to use this method. Instead it is more desirable to check if the array is empty before passing the value into libasynql. - * - * @return bool - */ - public function canBeEmpty() : bool{ - if(!$this->list){ - throw new InvalidStateException("canBeEmpty() is only available for list variables"); - } - - return $this->canEmpty; - } - - public function isNullable() : bool{ - return $this->nullable; - } - - public function getType() : string{ - return $this->type; - } - - /** - * @return mixed - */ - public function getDefault(){ - return $this->default; - } - - public function isOptional() : bool{ - return $this->default !== null; - } - - public function equals(GenericVariable $that, &$diff = null) : bool{ - if($this->name !== $that->name){ - $diff = "name"; - return false; - } - if($this->list !== $that->list){ - $diff = "isList"; - return false; - } - if($this->canEmpty !== $that->canEmpty){ - $diff = "canBeEmpty"; - return false; - } - if($this->type !== $that->type){ - $diff = "type"; - return false; - } - if($this->default !== $that->default){ - $diff = "defaultValue"; - return false; - } - return true; - } - - public function jsonSerialize(){ - return [ - "name" => $this->name, - "isList" => $this->list, - "canEmpty" => $this->canEmpty, - "type" => $this->type, - "default" => $this->default, - ]; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/MysqlStatementImpl.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/MysqlStatementImpl.php deleted file mode 100644 index e8e7a9b..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/MysqlStatementImpl.php +++ /dev/null @@ -1,108 +0,0 @@ -isList()){ - assert(is_array($value)); - if(empty($value)){ - if(!$variable->canBeEmpty()){ - throw new InvalidArgumentException("Cannot pass an empty array for :{$variable->getName()}"); - } - - return "('" . bin2hex(random_bytes(20)) . ")"; - } - - $unlist = $variable->unlist(); - return "(" . implode(",", array_map(function($value) use ($unlist, $placeHolder, &$outArgs){ - return $this->formatVariable($unlist, $value, $placeHolder, $outArgs); - }, $value)) . ")"; - } - - if($value === null){ - if(!$variable->isNullable()){ - throw new InvalidArgumentException("The variable :{$variable->getName()} is not nullable"); - } - return "NULL"; - } - - switch($variable->getType()){ - case GenericVariable::TYPE_BOOL: - assert(is_bool($value)); - return $value ? "1" : "0"; - - case GenericVariable::TYPE_INT: - assert(is_int($value)); - return (string) $value; - - case GenericVariable::TYPE_FLOAT: - assert(is_int($value) || is_float($value)); - if(!is_finite($value)){ - throw new InvalidArgumentException("Cannot encode $value in MySQL"); - } - return (string) $value; - - case GenericVariable::TYPE_STRING: - assert(is_string($value)); - if($placeHolder !== null){ - $outArgs[] = $value; - return $placeHolder; - } - - do{ - $varName = ":var" . rand(0, 10000000); - }while(isset($outArgs[$varName])); - $outArgs[$varName] = $value; - return " " . $varName . " "; - - case GenericVariable::TYPE_TIMESTAMP: - assert(is_int($value) || is_float($value)); - if($value === GenericVariable::TIME_NOW){ - return "CURRENT_TIMESTAMP"; - } - return "FROM_UNIXTIME($value)"; - } - - throw new RuntimeException("Unsupported variable type"); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/SqliteStatementImpl.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/SqliteStatementImpl.php deleted file mode 100644 index 427248d..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/generic/SqliteStatementImpl.php +++ /dev/null @@ -1,86 +0,0 @@ -isList()){ - assert(is_array($value)); - - // IN () works with SQLite3. - $unlist = $variable->unlist(); - return "(" . implode(",", array_map(function($value) use ($placeHolder, $unlist, &$outArgs){ - return $this->formatVariable($unlist, $value, $placeHolder, $outArgs); - }, $value)) . ")"; - } - - if($value === null){ - if(!$variable->isNullable()){ - throw new InvalidArgumentException("The variable :{$variable->getName()} is not nullable"); - } - - return "NULL"; - } - - switch($variable->getType()){ - case GenericVariable::TYPE_BOOL: - assert(is_bool($value)); - return $value ? "1" : "0"; - - case GenericVariable::TYPE_INT: - assert(is_int($value)); - return (string) $value; - - case GenericVariable::TYPE_FLOAT: - assert(is_int($value) || is_float($value)); - return (string) $value; - - case GenericVariable::TYPE_STRING: - assert(is_string($value)); - if(strpos($value, "\0") !== false){ - return "X'" . bin2hex($value) . "'"; - } - return "'" . SQLite3::escapeString($value) . "'"; - } - - throw new RuntimeException("Unsupported variable type"); - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/libasynql.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/libasynql.php deleted file mode 100644 index 0c942c5..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/libasynql.php +++ /dev/null @@ -1,177 +0,0 @@ -!libasynql::isPackaged(). - * - * @return DataConnector - * @throws SqlError if the connection could not be created - */ - public static function create(PluginBase $plugin, $configData, array $sqlMap, bool $logQueries = null) : DataConnector{ - if(!is_array($configData)){ - throw new ConfigException("Database settings are missing or incorrect"); - } - - $type = (string) $configData["type"]; - if($type === ""){ - throw new ConfigException("Database type is missing"); - } - - if(count($sqlMap) === 0){ - throw new InvalidArgumentException('Parameter $sqlMap cannot be empty'); - } - - $pdo = ($configData["prefer-pdo"] ?? false) && extension_loaded("pdo"); - - $dialect = null; - $placeHolder = null; - switch(strtolower($type)){ - case "sqlite": - case "sqlite3": - case "sq3": - if(!$pdo && !extension_loaded("sqlite3")){ - throw new ExtensionMissingException("sqlite3"); - } - - $fileName = self::resolvePath($plugin->getDataFolder(), $configData["sqlite"]["file"] ?? "data.sqlite"); - if($pdo){ - // TODO add PDO support - }else{ - $factory = Sqlite3Thread::createFactory($fileName); - } - $dialect = "sqlite"; - break; - case "mysql": - case "mysqli": - if(!$pdo && !extension_loaded("mysqli")){ - throw new ExtensionMissingException("mysqli"); - } - - if(!isset($configData["mysql"])){ - throw new ConfigException("Missing MySQL settings"); - } - - $cred = MysqlCredentials::fromArray($configData["mysql"], strtolower($plugin->getName())); - - if($pdo){ - // TODO add PDO support - }else{ - $factory = MysqliThread::createFactory($cred); - $placeHolder = "?"; - } - $dialect = "mysql"; - - break; - } - - if(!isset($dialect, $factory, $sqlMap[$dialect])){ - throw new ConfigException("Unsupported database type \"$type\". Try \"" . implode("\" or \"", array_keys($sqlMap)) . "\"."); - } - - $pool = new SqlThreadPool($factory, $configData["worker-limit"] ?? 1); - while(!$pool->connCreated()){ - usleep(1000); - } - if($pool->hasConnError()){ - throw new SqlError(SqlError::STAGE_CONNECT, $pool->getConnError()); - } - - $connector = new DataConnectorImpl($plugin, $pool, $placeHolder, $logQueries ?? !libasynql::isPackaged()); - foreach(is_string($sqlMap[$dialect]) ? [$sqlMap[$dialect]] : $sqlMap[$dialect] as $file){ - $resource = $plugin->getResource($file); - if($resource===null){ - throw new InvalidArgumentException("resources/$file does not exist"); - } - $connector->loadQueryFile($resource); - } - - return $connector; - } - - private static function resolvePath(string $folder, string $path) : string{ - if($path[0] === "/"){ - return $path; - } - if(Utils::getOS() === "win"){ - if($path[0] === "\\" || $path[1] === ":"){ - return $path; - } - } - return $folder . $path; - } -} - -/** - * An empty function accepting void parameters and returning void. Can be used as a dummy function. - */ -function nop() : void{ - -} - -libasynql::detectPackaged(); diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlColumnInfo.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlColumnInfo.php deleted file mode 100644 index b28bc92..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlColumnInfo.php +++ /dev/null @@ -1,48 +0,0 @@ -flags = $flags; - $this->mysqlType = $mysqlType; - } - - public function getFlags() : int{ - return $this->flags; - } - - public function hasFlag(int $flag) : bool{ - return ($this->flags & $flag) > 0; - } - - public function getMysqlType() : int{ - return $this->mysqlType; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlCredentials.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlCredentials.php deleted file mode 100644 index 87b4aea..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlCredentials.php +++ /dev/null @@ -1,152 +0,0 @@ - - * host: 127.0.0.1 - * username: root - * password: "" - * schema: {$defaultSchema} - * port: 3306 - * socket: "" - * - * - * @param array $array - * @param string|null $defaultSchema default null - * @return MysqlCredentials - * @throws ConfigException If schema is missing and $defaultSchema is null/not passed - */ - public static function fromArray(array $array, ?string $defaultSchema = null) : MysqlCredentials{ - if(!isset($defaultSchema, $array["schema"])){ - throw new ConfigException("The attribute \"schema\" is missing in the MySQL settings"); - } - return new MysqlCredentials($array["host"] ?? "127.0.0.1", $array["username"] ?? "root", - $array["password"] ?? "", $array["schema"] ?? $defaultSchema, $array["port"] ?? 3306, $array["socket"] ?? ""); - } - - /** - * Constructs a new {@link MysqlCredentials} by passing parameters directly. - * - * @param string $host - * @param string $username - * @param string $password - * @param string $schema - * @param int $port - * @param string $socket - */ - public function __construct(string $host, string $username, string $password, string $schema, int $port = 3306, string $socket = ""){ - $this->host = $host; - $this->username = $username; - $this->password = $password; - $this->schema = $schema; - $this->port = $port; - $this->socket = $socket; - } - - /** - * Creates a new mysqli instance - * - * @return mysqli - * - * @throws SqlError - */ - public function newMysqli() : mysqli{ - $mysqli = @new mysqli($this->host, $this->username, $this->password, $this->schema, $this->port, $this->socket); - if($mysqli->connect_error){ - throw new SqlError(SqlError::STAGE_CONNECT, $mysqli->connect_error); - } - return $mysqli; - } - - /** - * Reuses an existing mysqli instance - * - * @param mysqli $mysqli - * - * @throws SqlError - */ - public function reconnectMysqli(mysqli &$mysqli) : void{ - $mysqli->connect($this->host, $this->username, $this->password, $this->schema, $this->port, $this->socket); - if($mysqli->connect_error){ - throw new SqlError(SqlError::STAGE_CONNECT, $mysqli->connect_error); - } - } - - /** - * Produces a human-readable output without leaking password - * - * @return string - */ - public function __toString() : string{ - return "$this->username@$this->host:$this->port/schema,$this->socket"; - } - - /** - * Prepares value to be var_dump()'ed without leaking password - * - * @return array - */ - public function __debugInfo(){ - return [ - "host" => $this->host, - "username" => $this->username, - "password" => str_repeat("*", strlen($this->password)), - "schema" => $this->schema, - "port" => $this->port, - "socket" => $this->socket - ]; - } - - public function jsonSerialize() : array{ - return [ - "host" => $this->host, - "username" => $this->username, - "password" => $this->password, - "schema" => $this->schema, - "port" => $this->port, - "socket" => $this->socket - ]; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlFlags.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlFlags.php deleted file mode 100644 index f000b02..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/mysqli/MysqlFlags.php +++ /dev/null @@ -1,67 +0,0 @@ -credentials = serialize($credentials); - parent::__construct($notifier, $bufferSend, $bufferRecv); - } - - protected function createConn(&$mysqli) : ?string{ - /** @var MysqlCredentials $cred */ - $cred = unserialize($this->credentials); - try{ - $mysqli = $cred->newMysqli(); - return null; - }catch(SqlError $e){ - return $e->getErrorMessage(); - } - } - - protected function executeQuery($mysqli, int $mode, string $query, array $params) : SqlResult{ - assert($mysqli instanceof mysqli); - /** @var MysqlCredentials $cred */ - $cred = unserialize($this->credentials); - while(!$mysqli->ping()){ - $cred->reconnectMysqli($mysqli); - if($this->connError === null){ - break; - } - } - if(empty($params)){ - $result = $mysqli->query($query); - if($result === false){ - throw new SqlError(SqlError::STAGE_EXECUTE, $mysqli->error, $query, []); - } - switch($mode){ - case SqlThread::MODE_GENERIC: - case SqlThread::MODE_CHANGE: - case SqlThread::MODE_INSERT: - if($result instanceof mysqli_result){ - $result->close(); - } - if($mode === SqlThread::MODE_INSERT){ - return new SqlInsertResult($mysqli->affected_rows, $mysqli->insert_id); - } - if($mode === SqlThread::MODE_CHANGE){ - return new SqlChangeResult($mysqli->affected_rows); - } - return new SqlResult(); - - case SqlThread::MODE_SELECT: - $ret = $this->toSelectResult($result); - $result->close(); - return $ret; - } - }else{ - $stmt = $mysqli->prepare($query); - if(!($stmt instanceof mysqli_stmt)){ - throw new SqlError(SqlError::STAGE_PREPARE, $mysqli->error, $query, $params); - } - $types = implode(array_map(static function($param) use ($query, $params){ - if(is_string($param)){ - return "s"; - } - if(is_float($param)){ - return "d"; - } - if(is_int($param)){ - return "i"; - } - throw new SqlError(SqlError::STAGE_PREPARE, "Cannot bind value of type " . gettype($param), $query, $params); - }, $params)); - $stmt->bind_param($types, ...$params); - if(!$stmt->execute()){ - throw new SqlError(SqlError::STAGE_EXECUTE, $stmt->error, $query, $params); - } - switch($mode){ - case SqlThread::MODE_GENERIC: - $ret = new SqlResult(); - $stmt->close(); - return $ret; - - case SqlThread::MODE_CHANGE: - $ret = new SqlChangeResult($stmt->affected_rows); - $stmt->close(); - return $ret; - - case SqlThread::MODE_INSERT: - $ret = new SqlInsertResult($stmt->affected_rows, $stmt->insert_id); - $stmt->close(); - return $ret; - - case SqlThread::MODE_SELECT: - $set = $stmt->get_result(); - $ret = $this->toSelectResult($set); - $set->close(); - return $ret; - } - } - - throw new InvalidArgumentException("Unknown mode $mode"); - } - - private function toSelectResult(mysqli_result $result) : SqlSelectResult{ - $columns = []; - $columnFunc = []; - - while(($field = $result->fetch_field()) !== false){ - if($field->length === 1){ - if($field->type === MysqlTypes::TINY){ - $type = SqlColumnInfo::TYPE_BOOL; - $columnFunc[$field->name] = static function($tiny){ - return $tiny > 0; - }; - }elseif($field->type === MysqlTypes::BIT){ - $type = SqlColumnInfo::TYPE_BOOL; - $columnFunc[$field->name] = static function($bit){ - return $bit === "\1"; - }; - } - } - if($field->type === MysqlTypes::LONGLONG){ - $type = SqlColumnInfo::TYPE_INT; - $columnFunc[$field->name] = static function($longLong) use ($field){ - if($field->flags & MysqlFlags::UNSIGNED_FLAG){ - if(bccomp(strval($longLong), "9223372036854775807") === 1){ - $longLong = bcsub($longLong, "18446744073709551616"); - } - return (int) $longLong; - } - - return (int) $longLong; - }; - }elseif($field->flags & MysqlFlags::TIMESTAMP_FLAG){ - $type = SqlColumnInfo::TYPE_TIMESTAMP; - $columnFunc[$field->name] = static function($stamp){ - return strtotime($stamp); - }; - }elseif($field->type === MysqlTypes::NULL){ - $type = SqlColumnInfo::TYPE_NULL; - }elseif(in_array($field->type, [ - MysqlTypes::VARCHAR, - MysqlTypes::STRING, - MysqlTypes::VAR_STRING, - ], true)){ - $type = SqlColumnInfo::TYPE_STRING; - }elseif(in_array($field->type, [MysqlTypes::FLOAT, MysqlTypes::DOUBLE, MysqlTypes::DECIMAL, MysqlTypes::NEWDECIMAL], true)){ - $type = SqlColumnInfo::TYPE_FLOAT; - $columnFunc[$field->name] = "floatval"; - }elseif(in_array($field->type, [MysqlTypes::TINY, MysqlTypes::SHORT, MysqlTypes::INT24, MysqlTypes::LONG], true)){ - $type = SqlColumnInfo::TYPE_INT; - $columnFunc[$field->name] = "intval"; - } - if(!isset($type)){ - $type = SqlColumnInfo::TYPE_OTHER; - } - $columns[$field->name] = new MysqlColumnInfo($field->name, $type, $field->flags, $field->type); - } - - $rows = []; - while(($row = $result->fetch_assoc()) !== null){ - foreach($row as $col => &$cell){ - if($cell !== null && isset($columnFunc[$col])){ - $cell = $columnFunc[$col]($cell); - } - } - unset($cell); - $rows[] = $row; - } - - return new SqlSelectResult($columns, $rows); - } - - protected function close(&$mysqli) : void{ - assert($mysqli instanceof mysqli); - $mysqli->close(); - } - - public function getThreadName() : string{ - return __NAMESPACE__ . " connector #$this->slaveNumber"; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlChangeResult.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlChangeResult.php deleted file mode 100644 index 36ded59..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlChangeResult.php +++ /dev/null @@ -1,37 +0,0 @@ -affectedRows = $affectedRows; - } - - public function getAffectedRows() : int{ - return $this->affectedRows; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlColumnInfo.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlColumnInfo.php deleted file mode 100644 index 8ff2fe3..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlColumnInfo.php +++ /dev/null @@ -1,49 +0,0 @@ -name = $name; - $this->type = $type; - } - - public function getName() : string{ - return $this->name; - } - - public function getType() : string{ - return $this->type; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlInsertResult.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlInsertResult.php deleted file mode 100644 index 07b2ef7..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlInsertResult.php +++ /dev/null @@ -1,37 +0,0 @@ -insertId = $insertId; - } - - public function getInsertId() : int{ - return $this->insertId; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlSelectResult.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlSelectResult.php deleted file mode 100644 index ea3422c..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/result/SqlSelectResult.php +++ /dev/null @@ -1,70 +0,0 @@ -columnInfo = $columnInfo; - $this->rows = $rows; - } - - /** - * Returns the columns from the query - * - * @return SqlColumnInfo[] - */ - public function getColumnInfo() : array{ - return $this->columnInfo; - } - - /** - * Returns an array of rows. Each row is an array with keys as the (virtual) column name and values as the cell value. The type of cell values are juggled with the following special rules: - * - TINYINT(1) and BIT(1) in MySQL are expressed in bool - * - Signed long long, a.k.a. BIGINT [SIGNED], i.e. 64-bit unsigned integers, are expressed in int, because PocketMine only supports 64-bit machines. - * - Unsigned long long, a.k.a. BIGINT [SIGNED], i.e. 64-bit unsigned integers, are also expressed in int. If it exceeds PHP_INT_MAX, it overflows natively, i.e. PHP_INT_MAX + 1 becomes PHP_INT_MIN, which is different from both mysqli's implementation and PHP's behaviour. - * - Timestamps will be converted to a {@link https://php.net/date date()}-compatible UNIX timestamp in seconds. - * - Other types are juggled according to rules provided by the backend. - * - * If the query has multiple columns with the same name, the latter one overwrites the former ones. For example, the query SELECT 1 a, 2 a returns the result set [ ["a" => 2] ]. - * - * Also note that qualifying the column reference with the table name will not add the table name into the column name in the result set. For example, the query SELECT foo.qux, bar.qux will return the result set [ ["qux" => "the value in bar.qux"] ]. - * - * Therefore, use column aliases when the column names may duplicate. - * - * @return array[] - */ - public function getRows() : array{ - return $this->rows; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/sqlite3/Sqlite3Thread.php b/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/sqlite3/Sqlite3Thread.php deleted file mode 100644 index 566a6eb..0000000 --- a/src/Vecnavium/SkyBlocksPM/libs/poggit/libasynql/sqlite3/Sqlite3Thread.php +++ /dev/null @@ -1,153 +0,0 @@ -path = $path; - parent::__construct($notifier, $send, $recv); - } - - protected function createConn(&$sqlite) : ?string{ - try{ - $sqlite = new SQLite3($this->path); - $sqlite->busyTimeout(60000); // default value in SQLite2 - return null; - }catch(Exception $e){ - return $e->getMessage(); - } - } - - protected function executeQuery($sqlite, int $mode, string $query, array $params) : SqlResult{ - assert($sqlite instanceof SQLite3); - $stmt = $sqlite->prepare($query); - if($stmt === false){ - throw new SqlError(SqlError::STAGE_PREPARE, $sqlite->lastErrorMsg(), $query, $params); - } - foreach($params as $paramName => $param){ - $bind = $stmt->bindValue($paramName, $param); - if(!$bind){ - throw new SqlError(SqlError::STAGE_PREPARE, "when binding $paramName: " . $sqlite->lastErrorMsg(), $query, $params); - } - } - $result = $stmt->execute(); - if($result === false){ - throw new SqlError(SqlError::STAGE_EXECUTE, $sqlite->lastErrorMsg(), $query, $params); - } - switch($mode){ - case SqlThread::MODE_GENERIC: - $ret = new SqlResult(); - $result->finalize(); - $stmt->close(); - return $ret; - case SqlThread::MODE_CHANGE: - $ret = new SqlChangeResult($sqlite->changes()); - $result->finalize(); - $stmt->close(); - return $ret; - case SqlThread::MODE_INSERT: - $ret = new SqlInsertResult($sqlite->changes(), $sqlite->lastInsertRowID()); - $result->finalize(); - $stmt->close(); - return $ret; - case SqlThread::MODE_SELECT: - /** @var SqlColumnInfo[] $colInfo */ - $colInfo = []; - $rows = []; - while(is_array($row = $result->fetchArray(SQLITE3_ASSOC))){ - foreach(array_values($row) as $i => &$value){ - static $columnTypeMap = [ - SQLITE3_INTEGER => SqlColumnInfo::TYPE_INT, - SQLITE3_FLOAT => SqlColumnInfo::TYPE_FLOAT, - SQLITE3_TEXT => SqlColumnInfo::TYPE_STRING, - SQLITE3_BLOB => SqlColumnInfo::TYPE_STRING, - SQLITE3_NULL => SqlColumnInfo::TYPE_NULL, - ]; - $colInfo[$i] = new SqlColumnInfo($result->columnName($i), $columnTypeMap[$result->columnType($i)]); - if($colInfo[$i]->getType() === SqlColumnInfo::TYPE_FLOAT){ - if($value === "NAN"){ - $value = NAN; - }elseif($value === "INF"){ - $value = INF; - }elseif($value === "-INF"){ - $value = -INF; - } - } - } - unset($value); - $rows[] = $row; - } - $ret = new SqlSelectResult($colInfo, $rows); - $result->finalize(); - $stmt->close(); - return $ret; - } - - throw new InvalidArgumentException("Unknown mode $mode"); - } - - protected function close(&$resource) : void{ - assert($resource instanceof SQLite3); - $resource->close(); - } - - public function getThreadName() : string{ - return __NAMESPACE__ . " connector #$this->slaveNumber"; - } -} diff --git a/src/Vecnavium/SkyBlocksPM/listener/EventListener.php b/src/Vecnavium/SkyBlocksPM/listener/EventListener.php index fa3f906..914785a 100644 --- a/src/Vecnavium/SkyBlocksPM/listener/EventListener.php +++ b/src/Vecnavium/SkyBlocksPM/listener/EventListener.php @@ -6,15 +6,11 @@ use pocketmine\block\Chest; use pocketmine\block\Door; -use pocketmine\event\entity\EntityDamageByEntityEvent; -use pocketmine\event\entity\EntityItemPickupEvent; -use Vecnavium\SkyBlocksPM\skyblock\SkyblockSettingTypes; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; -use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; -use Vecnavium\SkyBlocksPM\player\Player; use pocketmine\event\block\BlockBreakEvent; use pocketmine\event\block\BlockPlaceEvent; +use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\event\entity\EntityItemPickupEvent; use pocketmine\event\Listener; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerInteractEvent; @@ -23,8 +19,12 @@ use pocketmine\item\Food; use pocketmine\player\Player as P; use pocketmine\utils\TextFormat; +use Vecnavium\SkyBlocksPM\player\Player; +use Vecnavium\SkyBlocksPM\skyblock\SkyBlock; +use Vecnavium\SkyBlocksPM\skyblock\SkyblockSettingTypes; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; use function in_array; -use function var_dump; +use function strval; class EventListener implements Listener { @@ -39,7 +39,7 @@ public function __construct(SkyBlocksPM $plugin) { * @return void */ public function onJoin(PlayerJoinEvent $event): void { - $player = $this->plugin->getPlayerManager()->getPlayerByPrefix($event->getPlayer()->getName()); + $player = $this->plugin->getPlayerManager()->getPlayer($event->getPlayer()->getName()); if (!$player instanceof Player) { $this->plugin->getPlayerManager()->loadPlayer($event->getPlayer()); } @@ -62,12 +62,12 @@ public function onBreak(BlockBreakEvent $event): void { $skyblock = $this->plugin->getSkyBlockManager()->getSkyBlockByWorld($event->getBlock()->getPosition()->getWorld()); if(!$skyblock instanceof SkyBlock) return; - if (!in_array($player->getName(), $skyblock->getMembers()) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_BREAK)) { + if (!in_array($player->getName(), $skyblock->getMembers(), true) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_BREAK)) { $event->cancel(); return; } - if ($this->plugin->getConfig()->getNested('settings.autoinv.enabled', true)) { + if ($this->plugin->getNewConfig()->settings->autoinv->enabled) { $drops = []; foreach ($event->getDrops() as $drop) { if (!$player->getInventory()->canAddItem($drop)) { @@ -77,11 +77,11 @@ public function onBreak(BlockBreakEvent $event): void { } } $event->setDrops([]); - if ($this->plugin->getConfig()->getNested('settings.autoinv.drop-when-full')) { + if ($this->plugin->getNewConfig()->settings->autoinv->dropWhenFull) { $event->setDrops($drops); } } - if ($this->plugin->getConfig()->getNested('settings.autoxp', true)) { + if ($this->plugin->getNewConfig()->settings->autoxp) { $player->getXpManager()->addXp($event->getXpDropAmount()); $event->setXpDropAmount(0); } @@ -92,10 +92,10 @@ public function onBreak(BlockBreakEvent $event): void { * @return void */ public function onPlace(BlockPlaceEvent $event): void { - $skyblock = $this->plugin->getSkyBlockManager()->getSkyBlockByWorld($event->getBlock()->getPosition()->getWorld()); + $skyblock = $this->plugin->getSkyBlockManager()->getSkyBlockByWorld($event->getPlayer()->getPosition()->getWorld()); if(!$skyblock instanceof SkyBlock) return; - if (!in_array($event->getPlayer()->getName(), $skyblock->getMembers()) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_PLACE)) { + if (!in_array($event->getPlayer()->getName(), $skyblock->getMembers(), true) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_PLACE)) { $event->cancel(); } } @@ -110,7 +110,7 @@ public function onInteract(PlayerInteractEvent $event): void { if(!$skyblock instanceof SkyBlock) return; if ($event->getItem() instanceof Food) return; - if (!in_array($player->getName(), $skyblock->getMembers())) { + if (!in_array($player->getName(), $skyblock->getMembers(), true)) { if ($event->getBlock() instanceof Chest) { if (!$skyblock->getSetting(SkyblockSettingTypes::SETTING_INTERACT_CHEST)) { $event->cancel(); @@ -137,35 +137,40 @@ public function onPlayerDamage(EntityDamageEvent $event): void { if ($event instanceof EntityDamageByEntityEvent && $skyblock->getSetting(SkyblockSettingTypes::SETTING_PVP)) return; - $type = match ($event->getCause()) { - EntityDamageEvent::CAUSE_LAVA => 'lava', - EntityDamageEvent::CAUSE_DROWNING => 'drown', - EntityDamageEvent::CAUSE_FALL => 'fall', - EntityDamageEvent::CAUSE_PROJECTILE => 'projectile', - EntityDamageEvent::CAUSE_FIRE => 'fire', - EntityDamageEvent::CAUSE_VOID => 'void', - EntityDamageEvent::CAUSE_STARVATION => 'hunger', - default => 'default' + $shouldCancel = match ($event->getCause()) { + EntityDamageEvent::CAUSE_LAVA => $this->plugin->getNewConfig()->settings->damage->lava, + EntityDamageEvent::CAUSE_DROWNING => $this->plugin->getNewConfig()->settings->damage->drown, + EntityDamageEvent::CAUSE_FALL => $this->plugin->getNewConfig()->settings->damage->fall, + EntityDamageEvent::CAUSE_PROJECTILE => $this->plugin->getNewConfig()->settings->damage->projectile, + EntityDamageEvent::CAUSE_FIRE => $this->plugin->getNewConfig()->settings->damage->fire, + EntityDamageEvent::CAUSE_VOID => $this->plugin->getNewConfig()->settings->damage->void, + EntityDamageEvent::CAUSE_STARVATION => $this->plugin->getNewConfig()->settings->damage->hunger, + default => $this->plugin->getNewConfig()->settings->damage->default }; - if ($this->plugin->getConfig()->getNested("settings.damage.$type", true)) { - $event->cancel(); - } + if ($shouldCancel) $event->cancel(); } + /** + * @param PlayerChatEvent $event + * @return void + */ public function onChat(PlayerChatEvent $event): void { $player = $event->getPlayer(); - if (!in_array($player->getName(), $this->plugin->getChat())) return; + if (!in_array($player->getName(), $this->plugin->getChat(), true)) return; + + $skyBlockPlayer = $this->plugin->getPlayerManager()->getPlayer($player->getName()); + if(!$skyBlockPlayer instanceof Player) return; - $skyBlock = $this->plugin->getSkyBlockManager()->getSkyBlockByUuid($this->plugin->getPlayerManager()->getPlayerByPrefix($player->getName())->getSkyBlock()); + $skyBlock = $this->plugin->getSkyBlockManager()->getSkyBlockByUuid($skyBlockPlayer->getSkyBlock()); if (!$skyBlock instanceof SkyBlock) { - $this->plugin->removePlayerFromChat($player); + $this->plugin->setPlayerChat($player, false); $player->sendMessage($this->plugin->getMessages()->getMessage('toggle-chat')); return; } foreach ($skyBlock->getMembers() as $member) { - $m = $this->plugin->getServer()->getPlayerByPrefix($member); + $m = $this->plugin->getServer()->getPlayerExact($member); if (!$m instanceof P) continue; - $m->sendMessage(str_replace(['{PLAYER}', '{MSG}'], [$player->getName(), $event->getMessage()], TextFormat::colorize($this->plugin->getMessages()->getMessageConfig()->get('skyblock-chat', '&d[SkyBlocksPM] &e[{PLAYER}] &6=> {MSG}')))); + $m->sendMessage(str_replace(['{PLAYER}', '{MSG}'], [$player->getName(), $event->getMessage()], TextFormat::colorize(strval($this->plugin->getMessages()->getMessageConfig()->get('skyblock-chat', '&d[SkyBlocksPM] &e[{PLAYER}] &6=> {MSG}'))))); } $event->cancel(); } @@ -177,7 +182,7 @@ public function onPickup(EntityItemPickupEvent $event): void { $skyblock = $this->plugin->getSkyBlockManager()->getSkyBlockByWorld($entity->getWorld()); if (!$skyblock instanceof SkyBlock) return; - if(!in_array($entity->getName(), $skyblock->getMembers()) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_PICKUP)) { + if(!in_array($entity->getName(), $skyblock->getMembers(), true) && !$skyblock->getSetting(SkyblockSettingTypes::SETTING_PICKUP)) { $event->cancel(); } } diff --git a/src/Vecnavium/SkyBlocksPM/messages/Messages.php b/src/Vecnavium/SkyBlocksPM/messages/Messages.php index 628c5a4..5c9fedd 100644 --- a/src/Vecnavium/SkyBlocksPM/messages/Messages.php +++ b/src/Vecnavium/SkyBlocksPM/messages/Messages.php @@ -4,27 +4,39 @@ namespace Vecnavium\SkyBlocksPM\messages; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; use pocketmine\utils\Config; use pocketmine\utils\TextFormat; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; +use function strval; class Messages { private Config $messages; + private string $prefix, $separator; public function __construct(SkyBlocksPM $plugin) { $this->messages = new Config($plugin->getDataFolder() . 'messages.yml', Config::YAML); + $this->prefix = strval($this->messages->get('prefix')); + $this->separator = strval($this->messages->get('separator')); } + /** + * @param string $msg + * @param string[] $args + * @return string + */ public function getMessage(string $msg, array $args = []): string { - $message = $this->messages->getNested("messages.$msg"); - foreach ($args as $key => $value) + $message = strval($this->messages->getNested("messages.$msg")); + foreach ($args as $key => $value) { $message = str_replace($key, $value, $message); - return TextFormat::colorize("{$this->messages->get('prefix')} {$this->messages->get('separator')} $message"); + } + return TextFormat::colorize("{$this->prefix} {$this->separator} $message"); } + /** + * @return Config + */ public function getMessageConfig(): Config { return $this->messages; } - } diff --git a/src/Vecnavium/SkyBlocksPM/player/Player.php b/src/Vecnavium/SkyBlocksPM/player/Player.php index 08ba788..294d49a 100644 --- a/src/Vecnavium/SkyBlocksPM/player/Player.php +++ b/src/Vecnavium/SkyBlocksPM/player/Player.php @@ -8,13 +8,11 @@ class Player { - private string $uuid, $name, $skyblocks; - - public function __construct(string $uuid, string $name, string $skyblocks) { - $this->uuid = $uuid; - $this->name = $name; - $this->skyblocks = $skyblocks; - } + public function __construct( + private string $uuid, + private string $name, + private string $skyblocks + ) {} /** * @return string @@ -23,15 +21,21 @@ public function getUuid(): string { return $this->uuid; } + /** + * @return string + */ public function getName(): string { return $this->name; } - + public function setName(string $name): void { $this->name = $name; $this->save(); } + /** + * @return string + */ public function getSkyBlock(): string { return $this->skyblocks; } diff --git a/src/Vecnavium/SkyBlocksPM/player/PlayerManager.php b/src/Vecnavium/SkyBlocksPM/player/PlayerManager.php index 71105a3..ef03289 100644 --- a/src/Vecnavium/SkyBlocksPM/player/PlayerManager.php +++ b/src/Vecnavium/SkyBlocksPM/player/PlayerManager.php @@ -4,20 +4,17 @@ namespace Vecnavium\SkyBlocksPM\player; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; use pocketmine\player\Player as P; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class PlayerManager { /** @var Player[] */ private array $players = []; - private SkyBlocksPM $plugin; - public function __construct(SkyBlocksPM $plugin) { - $this->plugin = $plugin; - } + public function __construct(private SkyBlocksPM $plugin) {} - public function loadPlayer(P $player) { + public function loadPlayer(P $player): void{ $this->plugin->getDataBase()->executeSelect( 'skyblockspm.player.load', [ @@ -30,17 +27,24 @@ function (array $rows) use ($player): void { } $name = $player->getName(); $this->players[$name] = new Player($rows[0]['uuid'], $rows[0]['name'], $rows[0]['skyblock']); - if ($name !== $rows[0]['name']) - $this->getPlayer($player)->setName($name); + if ($name !== $rows[0]['name']) { + $this->getPlayer($name)?->setName($name); + } $this->plugin->getSkyBlockManager()->loadSkyblock($rows[0]['skyblock']); } ); } - public function unloadPlayer(P $player) { - $this->plugin->getSkyBlockManager()->unloadSkyBlock($this->getPlayerByPrefix($player->getName())->getSkyBlock()); - if(isset($this->players[$player->getName()])) + public function unloadPlayer(P $player): void{ + $skyBlockPlayer = $this->getPlayer($player->getName()); + + if($skyBlockPlayer instanceof Player) { + $this->plugin->getSkyBlockManager()->unloadSkyBlock($skyBlockPlayer->getSkyBlock()); + } + + if(isset($this->players[$player->getName()])) { unset($this->players[$player->getName()]); + } } public function createPlayer(P $player): void { @@ -53,11 +57,12 @@ public function createPlayer(P $player): void { $this->players[$player->getName()] = new Player($player->getUniqueId()->toString(), $player->getName(), ''); } - public function getPlayer(P $player): ?Player { - return $this->players[$player->getName()] ?? null; - } - - public function getPlayerByPrefix(string $name): ?Player { + /** + * @param string $name + * @return Player|null + * @phpstan-return Player|null + */ + public function getPlayer(string $name): ?Player { return $this->players[$name] ?? null; } diff --git a/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlock.php b/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlock.php index 9022fdd..1688bb9 100644 --- a/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlock.php +++ b/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlock.php @@ -4,24 +4,29 @@ namespace Vecnavium\SkyBlocksPM\skyblock; -use Vecnavium\SkyBlocksPM\SkyBlocksPM; use pocketmine\math\Vector3; +use Vecnavium\SkyBlocksPM\SkyBlocksPM; class SkyBlock { - private string $uuid, $name, $leader, $world; - private array $members, $settings; - private Vector3 $spawn; - - public function __construct(string $uuid, string $name, string $leader, array $members, string $world, array $settings, Vector3 $spawn) { - $this->uuid = $uuid; - $this->name = $name; - $this->leader = $leader; - $this->members = $members; - $this->world = $world; - $this->settings = $settings; - $this->spawn = $spawn; - } + /** + * @param string $uuid + * @param string $name + * @param string $leader + * @param string[] $members + * @param string $world + * @param array $settings + * @param Vector3 $spawn + */ + public function __construct( + private string $uuid, + private string $name, + private string $leader, + private array $members, + private string $world, + private array $settings, + private Vector3 $spawn + ) {} /** * @return string @@ -61,14 +66,14 @@ public function setLeader(string $leader): void { } /** - * @return array + * @return string[] */ public function getMembers(): array { return $this->members; } /** - * @param array $members + * @param string[] $members */ public function setMembers(array $members): void { $this->members = $members; @@ -91,18 +96,22 @@ public function setWorld(string $world): void { } /** - * @return array + * @return array */ public function getSettings(): array { return $this->settings; } + /** + * @param string $setting + * @return bool + */ public function getSetting(string $setting): bool { - return isset($this->settings[$setting]) && $this->settings[$setting]; + return (isset($this->settings[$setting]) && $this->settings[$setting]); } /** - * @param array $settings + * @param array $settings */ public function updateSettings(array $settings): void { $this->settings = $settings; diff --git a/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlockManager.php b/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlockManager.php index 4aa5042..b970777 100644 --- a/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlockManager.php +++ b/src/Vecnavium/SkyBlocksPM/skyblock/SkyBlockManager.php @@ -1,24 +1,22 @@ plugin = $plugin; - } + public function __construct(private SkyBlocksPM $plugin) {} public function loadSkyblock(string $uuid): void { $this->plugin->getDataBase()->executeSelect( @@ -30,27 +28,36 @@ function (array $rows): void { if (count($rows) == 0) return; $row = $rows[0]; if(isset($this->SkyBlocks[$row['uuid']])) return; - $spawn = (array)json_decode($row['spawn']); - $this->SkyBlocks[$row['uuid']] = new SkyBlock($row['uuid'], $row['name'], $row['leader'], explode(',', $row['members']), $row['world'], (array)json_decode($row['settings']), new Vector3($spawn["x"], $spawn["y"], $spawn['z'])); + /** @var array $spawn */ + $spawn = (array)json_decode($row['spawn'], true); + /** @var array $settings */ + $settings = (array)json_decode($row['settings'], true); + $this->SkyBlocks[$row['uuid']] = new SkyBlock($row['uuid'], $row['name'], $row['leader'], explode(',', $row['members']), $row['world'], $settings, new Vector3($spawn['x'], $spawn['y'], $spawn['z'])); $this->plugin->getServer()->getWorldManager()->loadWorld($row['world']); $this->worlds[] = $row['world']; } ); } - public function unloadSkyBlock(string $uuid) { + public function unloadSkyBlock(string $uuid): void{ $skyblock = $this->getSkyBlockByUuid($uuid); - if (!$skyblock instanceof SkyBlock) - return; - foreach ($this->getSkyBlockByUuid($uuid)->getMembers() as $member) { - if ($this->plugin->getPlayerManager()->getPlayerByPrefix($member) instanceof Player) - return; + if (!$skyblock instanceof SkyBlock) return; + + foreach ($skyblock->getMembers() as $member) { + if ($this->plugin->getPlayerManager()->getPlayer($member) instanceof Player) return; } - $this->plugin->getServer()->getWorldManager()->unloadWorld($this->plugin->getServer()->getWorldManager()->getWorldByName($this->getSkyBlockByUuid($uuid)->getWorld())); + + $world = $this->plugin->getServer()->getWorldManager()->getWorldByName($skyblock->getWorld()); + if(!$world instanceof World) return; + $this->plugin->getServer()->getWorldManager()->unloadWorld($world); + unset($this->SkyBlocks[$uuid]); } public function createSkyBlock(string $uuid, Player $player, string $name, World $world): void { + $skyBlockPlayer = $this->plugin->getPlayerManager()->getPlayer($player->getName()); + if(!$skyBlockPlayer instanceof Player) return; + $spawn = $world->getSpawnLocation(); $SkyBlock = new SkyBlock($uuid, $name, $player->getName(), [$player->getName()], $world->getFolderName(), ['visit' => true, 'pvp' => false, 'interact_chest' => false, 'interact_door' => false,'pickup' => false, 'break' => false, 'place' => false], $spawn); $this->SkyBlocks[$uuid] = $SkyBlock; @@ -68,15 +75,22 @@ public function createSkyBlock(string $uuid, Player $player, string $name, World 'z' => $spawn->getZ() ]) ]); - $skyBlockPlayer = $this->plugin->getPlayerManager()->getPlayerByPrefix($player->getName()); $skyBlockPlayer->setSkyBlock($uuid); $SkyBlock->save(); } + /** + * @param string $uuid + * @return SkyBlock|null + */ public function getSkyBlockByUuid(string $uuid): ?SkyBlock { return $this->SkyBlocks[$uuid] ?? null; } + /** + * @param string $name + * @return SkyBlock|null + */ public function getSkyBlock(string $name): ?SkyBlock { foreach ($this->SkyBlocks as $SkyBlock) { if ($SkyBlock->getName() == $name) return $SkyBlock; @@ -84,6 +98,10 @@ public function getSkyBlock(string $name): ?SkyBlock { return null; } + /** + * @param World $world + * @return SkyBlock|null + */ public function getSkyBlockByWorld(World $world): ?SkyBlock { foreach ($this->SkyBlocks as $SkyBlock) { if ($SkyBlock->getWorld() == $world->getFolderName()) return $SkyBlock; @@ -91,8 +109,12 @@ public function getSkyBlockByWorld(World $world): ?SkyBlock { return null; } + /** + * @param string $world + * @return bool + */ public function isSkyBlockWorld(string $world): bool { - if (in_array($world, $this->worlds)) return true; + if (in_array($world, $this->worlds, true)) return true; return false; } diff --git a/tools/phpstan/composer.json b/tools/phpstan/composer.json new file mode 100644 index 0000000..f66b46d --- /dev/null +++ b/tools/phpstan/composer.json @@ -0,0 +1,37 @@ +{ + "name": "vecnavium/skyblockspm", + "repositories": [{ + "type": "package", + "package": { + "name": "paroxity/commando", + "version": "3.0.0", + "source": { + "url": "https://github.com/Paroxity/Commando.git", + "type": "git", + "reference": "master" + }, + "autoload": { + "classmap": ["src/"] + } + } + }], + "require": { + "phpstan/phpstan": "1.4.6", + "pocketmine/pocketmine-mp": "5.1.2", + "phpstan/phpstan-strict-rules": "^1.0", + "phpstan/extension-installer": "^1.0", + "paroxity/commando": "^3.0.0", + "sylvrs/libmarshal": "^1.4.3", + "sof3/libasynql": "4.2.0" + }, + "autoload": { + "psr-0": { + "Vecnavium\\SkyBlocksPM\\": "../../src/" + } + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } + } +} diff --git a/tools/phpstan/phpstan.neon.dist b/tools/phpstan/phpstan.neon.dist new file mode 100644 index 0000000..77b4338 --- /dev/null +++ b/tools/phpstan/phpstan.neon.dist @@ -0,0 +1,7 @@ +parameters: + level: 9 + paths: + - ../../src + excludePaths: + - ../../src/Vecnavium/SkyBlocksPM/libs + - ../../src/Vecnavium/SkyBlocksPM/CheckUpdateTask.php \ No newline at end of file