Removed pocketmine subdirectory, map PSR-4 style

This commit is contained in:
Dylan K. Taylor
2019-07-30 19:14:57 +01:00
parent 7a77d3dc30
commit 5499ac620c
1044 changed files with 3 additions and 3 deletions

334
src/command/Command.php Normal file
View File

@@ -0,0 +1,334 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
/**
* Command handling related classes
*/
namespace pocketmine\command;
use pocketmine\command\utils\CommandException;
use pocketmine\lang\TextContainer;
use pocketmine\lang\TranslationContainer;
use pocketmine\permission\PermissionManager;
use pocketmine\Server;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\TextFormat;
use function explode;
use function str_replace;
abstract class Command{
/** @var string */
private $name;
/** @var string */
private $nextLabel;
/** @var string */
private $label;
/** @var string[] */
private $aliases = [];
/**
* @var string[]
*/
private $activeAliases = [];
/** @var CommandMap */
private $commandMap = null;
/** @var string */
protected $description = "";
/** @var string */
protected $usageMessage;
/** @var string|null */
private $permission = null;
/** @var string */
private $permissionMessage = null;
/** @var TimingsHandler */
public $timings;
/**
* @param string $name
* @param string $description
* @param string $usageMessage
* @param string[] $aliases
*/
public function __construct(string $name, string $description = "", ?string $usageMessage = null, array $aliases = []){
$this->name = $name;
$this->setLabel($name);
$this->setDescription($description);
$this->usageMessage = $usageMessage ?? ("/" . $name);
$this->setAliases($aliases);
}
/**
* @param CommandSender $sender
* @param string $commandLabel
* @param string[] $args
*
* @return mixed
* @throws CommandException
*/
abstract public function execute(CommandSender $sender, string $commandLabel, array $args);
/**
* @return string
*/
public function getName() : string{
return $this->name;
}
/**
* @return string|null
*/
public function getPermission() : ?string{
return $this->permission;
}
/**
* @param string|null $permission
*/
public function setPermission(?string $permission) : void{
$this->permission = $permission;
}
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermission(CommandSender $target) : bool{
if($this->testPermissionSilent($target)){
return true;
}
if($this->permissionMessage === null){
$target->sendMessage($target->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
}elseif($this->permissionMessage !== ""){
$target->sendMessage(str_replace("<permission>", $this->permission, $this->permissionMessage));
}
return false;
}
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermissionSilent(CommandSender $target) : bool{
if($this->permission === null or $this->permission === ""){
return true;
}
foreach(explode(";", $this->permission) as $permission){
if($target->hasPermission($permission)){
return true;
}
}
return false;
}
/**
* @return string
*/
public function getLabel() : string{
return $this->label;
}
public function setLabel(string $name) : bool{
$this->nextLabel = $name;
if(!$this->isRegistered()){
if($this->timings instanceof TimingsHandler){
$this->timings->remove();
}
$this->timings = new TimingsHandler("** Command: " . $name);
$this->label = $name;
return true;
}
return false;
}
/**
* Registers the command into a Command map
*
* @param CommandMap $commandMap
*
* @return bool
*/
public function register(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){
$this->commandMap = $commandMap;
return true;
}
return false;
}
/**
* @param CommandMap $commandMap
*
* @return bool
*/
public function unregister(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){
$this->commandMap = null;
$this->activeAliases = $this->aliases;
$this->label = $this->nextLabel;
return true;
}
return false;
}
/**
* @param CommandMap $commandMap
*
* @return bool
*/
private function allowChangesFrom(CommandMap $commandMap) : bool{
return $this->commandMap === null or $this->commandMap === $commandMap;
}
/**
* @return bool
*/
public function isRegistered() : bool{
return $this->commandMap !== null;
}
/**
* @return string[]
*/
public function getAliases() : array{
return $this->activeAliases;
}
/**
* @return string|null
*/
public function getPermissionMessage() : ?string{
return $this->permissionMessage;
}
/**
* @return string
*/
public function getDescription() : string{
return $this->description;
}
/**
* @return string
*/
public function getUsage() : string{
return $this->usageMessage;
}
/**
* @param string[] $aliases
*/
public function setAliases(array $aliases) : void{
$this->aliases = $aliases;
if(!$this->isRegistered()){
$this->activeAliases = $aliases;
}
}
/**
* @param string $description
*/
public function setDescription(string $description) : void{
$this->description = $description;
}
/**
* @param string $permissionMessage
*/
public function setPermissionMessage(string $permissionMessage) : void{
$this->permissionMessage = $permissionMessage;
}
/**
* @param string $usage
*/
public function setUsage(string $usage) : void{
$this->usageMessage = $usage;
}
/**
* @param CommandSender $source
* @param TextContainer|string $message
* @param bool $sendToSource
*/
public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{
$users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE);
if($message instanceof TextContainer){
$m = clone $message;
$result = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($m->getText()) !== $m->getText() ? "%" : "") . $m->getText() . "]";
$colored = TextFormat::GRAY . TextFormat::ITALIC . $result;
$m->setText($result);
$result = clone $m;
$m->setText($colored);
$colored = clone $m;
}else{
$result = new TranslationContainer("chat.type.admin", [$source->getName(), $message]);
$colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%chat.type.admin", [$source->getName(), $message]);
}
if($sendToSource and !($source instanceof ConsoleCommandSender)){
$source->sendMessage($message);
}
foreach($users as $user){
if($user instanceof CommandSender){
if($user instanceof ConsoleCommandSender){
$user->sendMessage($result);
}elseif($user !== $source){
$user->sendMessage($colored);
}
}
}
}
/**
* @return string
*/
public function __toString() : string{
return $this->name;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
interface CommandExecutor{
/**
* @param CommandSender $sender
* @param Command $command
* @param string $label
* @param string[] $args
*
* @return bool
*/
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool;
}

View File

@@ -0,0 +1,65 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
interface CommandMap{
/**
* @param string $fallbackPrefix
* @param Command[] $commands
*/
public function registerAll(string $fallbackPrefix, array $commands) : void;
/**
* @param string $fallbackPrefix
* @param Command $command
* @param string|null $label
*
* @return bool
*/
public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool;
/**
* @param CommandSender $sender
* @param string $cmdLine
*
* @return bool
*/
public function dispatch(CommandSender $sender, string $cmdLine) : bool;
/**
* @return void
*/
public function clearCommands() : void;
/**
* @param string $name
*
* @return Command|null
*/
public function getCommand(string $name) : ?Command;
}

View File

@@ -0,0 +1,203 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\snooze\SleeperNotifier;
use pocketmine\thread\Thread;
use pocketmine\utils\Utils;
use function extension_loaded;
use function fclose;
use function fgets;
use function fopen;
use function fstat;
use function getopt;
use function is_resource;
use function microtime;
use function preg_replace;
use function readline;
use function readline_add_history;
use function stream_isatty;
use function stream_select;
use function trim;
use function usleep;
use const STDIN;
class CommandReader extends Thread{
public const TYPE_READLINE = 0;
public const TYPE_STREAM = 1;
public const TYPE_PIPED = 2;
/** @var resource */
private static $stdin;
/** @var \Threaded */
protected $buffer;
private $shutdown = false;
private $type = self::TYPE_STREAM;
/** @var SleeperNotifier|null */
private $notifier;
public function __construct(?SleeperNotifier $notifier = null){
$this->buffer = new \Threaded;
$this->notifier = $notifier;
$opts = getopt("", ["disable-readline", "enable-readline"]);
if(extension_loaded("readline") and (Utils::getOS() === "win" ? isset($opts["enable-readline"]) : !isset($opts["disable-readline"])) and !$this->isPipe(STDIN)){
$this->type = self::TYPE_READLINE;
}
}
public function shutdown() : void{
$this->shutdown = true;
}
public function quit() : void{
$wait = microtime(true) + 0.5;
while(microtime(true) < $wait){
if($this->isRunning()){
usleep(100000);
}else{
parent::quit();
return;
}
}
$message = "Thread blocked for unknown reason";
if($this->type === self::TYPE_PIPED){
$message = "STDIN is being piped from another location and the pipe is blocked, cannot stop safely";
}
throw new \ThreadException($message);
}
private function initStdin() : void{
if(is_resource(self::$stdin)){
fclose(self::$stdin);
}
self::$stdin = fopen("php://stdin", "r");
if($this->isPipe(self::$stdin)){
$this->type = self::TYPE_PIPED;
}else{
$this->type = self::TYPE_STREAM;
}
}
/**
* Checks if the specified stream is a FIFO pipe.
*
* @param resource $stream
*
* @return bool
*/
private function isPipe($stream) : bool{
return is_resource($stream) and (!stream_isatty($stream) or ((fstat($stream)["mode"] & 0170000) === 0010000));
}
/**
* Reads a line from the console and adds it to the buffer. This method may block the thread.
*
* @return bool if the main execution should continue reading lines
*/
private function readLine() : bool{
$line = "";
if($this->type === self::TYPE_READLINE){
if(($raw = readline("> ")) !== false and ($line = trim($raw)) !== ""){
readline_add_history($line);
}else{
return true;
}
}else{
if(!is_resource(self::$stdin)){
$this->initStdin();
}
switch($this->type){
/** @noinspection PhpMissingBreakStatementInspection */
case self::TYPE_STREAM:
//stream_select doesn't work on piped streams for some reason
$r = [self::$stdin];
if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds
return true;
}elseif($count === false){ //stream error
$this->initStdin();
}
case self::TYPE_PIPED:
if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF
$this->initStdin();
$this->synchronized(function(){
$this->wait(200000);
}); //prevent CPU waste if it's end of pipe
return true; //loop back round
}
$line = trim($raw);
break;
}
}
if($line !== ""){
$this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line);
if($this->notifier !== null){
$this->notifier->wakeupSleeper();
}
}
return true;
}
/**
* Reads a line from console, if available. Returns null if not available
*
* @return string|null
*/
public function getLine() : ?string{
if($this->buffer->count() !== 0){
return (string) $this->buffer->shift();
}
return null;
}
protected function onRun() : void{
if($this->type !== self::TYPE_READLINE){
$this->initStdin();
}
while(!$this->shutdown and $this->readLine());
if($this->type !== self::TYPE_READLINE){
fclose(self::$stdin);
}
}
public function getThreadName() : string{
return "Console";
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\lang\TextContainer;
use pocketmine\permission\Permissible;
use pocketmine\Server;
interface CommandSender extends Permissible{
/**
* @param TextContainer|string $message
*/
public function sendMessage($message) : void;
/**
* @return Server
*/
public function getServer() : Server;
/**
* @return string
*/
public function getName() : string;
/**
* Returns the line height of the command-sender's screen. Used for determining sizes for command output pagination
* such as in the /help command.
*
* @return int
*/
public function getScreenLineHeight() : int;
/**
* Sets the line height used for command output pagination for this command sender. `null` will reset it to default.
*
* @param int|null $height
*/
public function setScreenLineHeight(?int $height) : void;
}

View File

@@ -0,0 +1,98 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\lang\TextContainer;
use pocketmine\permission\PermissibleBase;
use pocketmine\permission\PermissibleDelegateTrait;
use pocketmine\Server;
use function explode;
use function trim;
use const PHP_INT_MAX;
class ConsoleCommandSender implements CommandSender{
use PermissibleDelegateTrait;
/** @var int|null */
protected $lineHeight = null;
public function __construct(){
$this->perm = new PermissibleBase($this);
}
/**
* @return Server
*/
public function getServer() : Server{
return Server::getInstance();
}
/**
* @param TextContainer|string $message
*/
public function sendMessage($message) : void{
$server = $this->getServer();
if($message instanceof TextContainer){
$message = $server->getLanguage()->translate($message);
}else{
$message = $server->getLanguage()->translateString($message);
}
foreach(explode("\n", trim($message)) as $line){
$server->getLogger()->info($line);
}
}
/**
* @return string
*/
public function getName() : string{
return "CONSOLE";
}
/**
* @return bool
*/
public function isOp() : bool{
return true;
}
/**
* @param bool $value
*/
public function setOp(bool $value) : void{
}
public function getScreenLineHeight() : int{
return $this->lineHeight ?? PHP_INT_MAX;
}
public function setScreenLineHeight(?int $height) : void{
if($height !== null and $height < 1){
throw new \InvalidArgumentException("Line height must be at least 1");
}
$this->lineHeight = $height;
}
}

View File

@@ -0,0 +1,156 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\Server;
use pocketmine\utils\TextFormat;
use function count;
use function ord;
use function strlen;
use function strpos;
use function substr;
class FormattedCommandAlias extends Command{
private $formatStrings = [];
/**
* @param string $alias
* @param string[] $formatStrings
*/
public function __construct(string $alias, array $formatStrings){
parent::__construct($alias);
$this->formatStrings = $formatStrings;
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
$commands = [];
$result = false;
foreach($this->formatStrings as $formatString){
try{
$commands[] = $this->buildCommand($formatString, $args);
}catch(\InvalidArgumentException $e){
$sender->sendMessage(TextFormat::RED . $e->getMessage());
return false;
}
}
foreach($commands as $command){
$result |= Server::getInstance()->dispatchCommand($sender, $command, true);
}
return (bool) $result;
}
/**
* @param string $formatString
* @param array $args
*
* @return string
*/
private function buildCommand(string $formatString, array $args) : string{
$index = strpos($formatString, '$');
while($index !== false){
$start = $index;
if($index > 0 and $formatString[$start - 1] === "\\"){
$formatString = substr($formatString, 0, $start - 1) . substr($formatString, $start);
$index = strpos($formatString, '$', $index);
continue;
}
$required = false;
if($formatString[$index + 1] == '$'){
$required = true;
++$index;
}
++$index;
$argStart = $index;
while($index < strlen($formatString) and self::inRange(ord($formatString[$index]) - 48, 0, 9)){
++$index;
}
if($argStart === $index){
throw new \InvalidArgumentException("Invalid replacement token");
}
$position = (int) substr($formatString, $argStart, $index);
if($position === 0){
throw new \InvalidArgumentException("Invalid replacement token");
}
--$position;
$rest = false;
if($index < strlen($formatString) and $formatString[$index] === "-"){
$rest = true;
++$index;
}
$end = $index;
if($required and $position >= count($args)){
throw new \InvalidArgumentException("Missing required argument " . ($position + 1));
}
$replacement = "";
if($rest and $position < count($args)){
for($i = $position, $c = count($args); $i < $c; ++$i){
if($i !== $position){
$replacement .= " ";
}
$replacement .= $args[$i];
}
}elseif($position < count($args)){
$replacement .= $args[$position];
}
$formatString = substr($formatString, 0, $start) . $replacement . substr($formatString, $end);
$index = $start + strlen($replacement);
$index = strpos($formatString, '$', $index);
}
return $formatString;
}
/**
* @param int $i
* @param int $j
* @param int $k
*
* @return bool
*/
private static function inRange(int $i, int $j, int $k) : bool{
return $i >= $j and $i <= $k;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\plugin\Plugin;
class PluginCommand extends Command implements PluginIdentifiableCommand{
/** @var Plugin */
private $owningPlugin;
/** @var CommandExecutor */
private $executor;
/**
* @param string $name
* @param Plugin $owner
*/
public function __construct(string $name, Plugin $owner){
parent::__construct($name);
$this->owningPlugin = $owner;
$this->executor = $owner;
$this->usageMessage = "";
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->owningPlugin->isEnabled()){
return false;
}
if(!$this->testPermission($sender)){
return false;
}
$success = $this->executor->onCommand($sender, $this, $commandLabel, $args);
if(!$success and $this->usageMessage !== ""){
throw new InvalidCommandSyntaxException();
}
return $success;
}
public function getExecutor() : CommandExecutor{
return $this->executor;
}
/**
* @param CommandExecutor $executor
*/
public function setExecutor(CommandExecutor $executor){
$this->executor = $executor;
}
/**
* @return Plugin
*/
public function getPlugin() : Plugin{
return $this->owningPlugin;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\plugin\Plugin;
interface PluginIdentifiableCommand{
/**
* @return Plugin
*/
public function getPlugin() : Plugin;
}

View File

@@ -0,0 +1,348 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\command\defaults\BanCommand;
use pocketmine\command\defaults\BanIpCommand;
use pocketmine\command\defaults\BanListCommand;
use pocketmine\command\defaults\DefaultGamemodeCommand;
use pocketmine\command\defaults\DeopCommand;
use pocketmine\command\defaults\DifficultyCommand;
use pocketmine\command\defaults\DumpMemoryCommand;
use pocketmine\command\defaults\EffectCommand;
use pocketmine\command\defaults\EnchantCommand;
use pocketmine\command\defaults\GamemodeCommand;
use pocketmine\command\defaults\GarbageCollectorCommand;
use pocketmine\command\defaults\GiveCommand;
use pocketmine\command\defaults\HelpCommand;
use pocketmine\command\defaults\KickCommand;
use pocketmine\command\defaults\KillCommand;
use pocketmine\command\defaults\ListCommand;
use pocketmine\command\defaults\MeCommand;
use pocketmine\command\defaults\OpCommand;
use pocketmine\command\defaults\PardonCommand;
use pocketmine\command\defaults\PardonIpCommand;
use pocketmine\command\defaults\ParticleCommand;
use pocketmine\command\defaults\PluginsCommand;
use pocketmine\command\defaults\SaveCommand;
use pocketmine\command\defaults\SaveOffCommand;
use pocketmine\command\defaults\SaveOnCommand;
use pocketmine\command\defaults\SayCommand;
use pocketmine\command\defaults\SeedCommand;
use pocketmine\command\defaults\SetWorldSpawnCommand;
use pocketmine\command\defaults\SpawnpointCommand;
use pocketmine\command\defaults\StatusCommand;
use pocketmine\command\defaults\StopCommand;
use pocketmine\command\defaults\TeleportCommand;
use pocketmine\command\defaults\TellCommand;
use pocketmine\command\defaults\TimeCommand;
use pocketmine\command\defaults\TimingsCommand;
use pocketmine\command\defaults\TitleCommand;
use pocketmine\command\defaults\TransferServerCommand;
use pocketmine\command\defaults\VanillaCommand;
use pocketmine\command\defaults\VersionCommand;
use pocketmine\command\defaults\WhitelistCommand;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\Server;
use function array_shift;
use function count;
use function explode;
use function implode;
use function min;
use function preg_match_all;
use function stripslashes;
use function strpos;
use function strtolower;
use function trim;
class SimpleCommandMap implements CommandMap{
/**
* @var Command[]
*/
protected $knownCommands = [];
/** @var Server */
private $server;
public function __construct(Server $server){
$this->server = $server;
$this->setDefaultCommands();
}
private function setDefaultCommands() : void{
$this->registerAll("pocketmine", [
new BanCommand("ban"),
new BanIpCommand("ban-ip"),
new BanListCommand("banlist"),
new DefaultGamemodeCommand("defaultgamemode"),
new DeopCommand("deop"),
new DifficultyCommand("difficulty"),
new DumpMemoryCommand("dumpmemory"),
new EffectCommand("effect"),
new EnchantCommand("enchant"),
new GamemodeCommand("gamemode"),
new GarbageCollectorCommand("gc"),
new GiveCommand("give"),
new HelpCommand("help"),
new KickCommand("kick"),
new KillCommand("kill"),
new ListCommand("list"),
new MeCommand("me"),
new OpCommand("op"),
new PardonCommand("pardon"),
new PardonIpCommand("pardon-ip"),
new ParticleCommand("particle"),
new PluginsCommand("plugins"),
new SaveCommand("save-all"),
new SaveOffCommand("save-off"),
new SaveOnCommand("save-on"),
new SayCommand("say"),
new SeedCommand("seed"),
new SetWorldSpawnCommand("setworldspawn"),
new SpawnpointCommand("spawnpoint"),
new StatusCommand("status"),
new StopCommand("stop"),
new TeleportCommand("tp"),
new TellCommand("tell"),
new TimeCommand("time"),
new TimingsCommand("timings"),
new TitleCommand("title"),
new TransferServerCommand("transferserver"),
new VersionCommand("version"),
new WhitelistCommand("whitelist")
]);
}
public function registerAll(string $fallbackPrefix, array $commands) : void{
foreach($commands as $command){
$this->register($fallbackPrefix, $command);
}
}
/**
* @param string $fallbackPrefix
* @param Command $command
* @param string|null $label
*
* @return bool
*/
public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool{
if($label === null){
$label = $command->getName();
}
$label = trim($label);
$fallbackPrefix = strtolower(trim($fallbackPrefix));
$registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
$aliases = $command->getAliases();
foreach($aliases as $index => $alias){
if(!$this->registerAlias($command, true, $fallbackPrefix, $alias)){
unset($aliases[$index]);
}
}
$command->setAliases($aliases);
if(!$registered){
$command->setLabel($fallbackPrefix . ":" . $label);
}
$command->register($this);
return $registered;
}
/**
* @param Command $command
*
* @return bool
*/
public function unregister(Command $command) : bool{
foreach($this->knownCommands as $lbl => $cmd){
if($cmd === $command){
unset($this->knownCommands[$lbl]);
}
}
$command->unregister($this);
return true;
}
/**
* @param Command $command
* @param bool $isAlias
* @param string $fallbackPrefix
* @param string $label
*
* @return bool
*/
private function registerAlias(Command $command, bool $isAlias, string $fallbackPrefix, string $label) : bool{
$this->knownCommands[$fallbackPrefix . ":" . $label] = $command;
if(($command instanceof VanillaCommand or $isAlias) and isset($this->knownCommands[$label])){
return false;
}
if(isset($this->knownCommands[$label]) and $this->knownCommands[$label]->getLabel() !== null and $this->knownCommands[$label]->getLabel() === $label){
return false;
}
if(!$isAlias){
$command->setLabel($label);
}
$this->knownCommands[$label] = $command;
return true;
}
/**
* Returns a command to match the specified command line, or null if no matching command was found.
* This method is intended to provide capability for handling commands with spaces in their name.
* The referenced parameters will be modified accordingly depending on the resulting matched command.
*
* @param string &$commandName
* @param string[] &$args
*
* @return Command|null
*/
public function matchCommand(string &$commandName, array &$args) : ?Command{
$count = min(count($args), 255);
for($i = 0; $i < $count; ++$i){
$commandName .= array_shift($args);
if(($command = $this->getCommand($commandName)) instanceof Command){
return $command;
}
$commandName .= " ";
}
return null;
}
public function dispatch(CommandSender $sender, string $commandLine) : bool{
$args = [];
preg_match_all('/"((?:\\\\.|[^\\\\"])*)"|(\S+)/u', $commandLine, $matches);
foreach($matches[0] as $k => $_){
for($i = 1; $i <= 2; ++$i){
if($matches[$i][$k] !== ""){
$args[$k] = stripslashes($matches[$i][$k]);
break;
}
}
}
$sentCommandLabel = "";
$target = $this->matchCommand($sentCommandLabel, $args);
if($target === null){
return false;
}
$target->timings->startTiming();
try{
$target->execute($sender, $sentCommandLabel, $args);
}catch(InvalidCommandSyntaxException $e){
$sender->sendMessage($this->server->getLanguage()->translateString("commands.generic.usage", [$target->getUsage()]));
}finally{
$target->timings->stopTiming();
}
return true;
}
public function clearCommands() : void{
foreach($this->knownCommands as $command){
$command->unregister($this);
}
$this->knownCommands = [];
$this->setDefaultCommands();
}
public function getCommand(string $name) : ?Command{
return $this->knownCommands[$name] ?? null;
}
/**
* @return Command[]
*/
public function getCommands() : array{
return $this->knownCommands;
}
/**
* @return void
*/
public function registerServerAliases() : void{
$values = $this->server->getCommandAliases();
foreach($values as $alias => $commandStrings){
if(strpos($alias, ":") !== false){
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.illegal", [$alias]));
continue;
}
$targets = [];
$bad = [];
$recursive = [];
foreach($commandStrings as $commandString){
$args = explode(" ", $commandString);
$commandName = "";
$command = $this->matchCommand($commandName, $args);
if($command === null){
$bad[] = $commandString;
}elseif($commandName === $alias){
$recursive[] = $commandString;
}else{
$targets[] = $commandString;
}
}
if(!empty($recursive)){
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.recursive", [$alias, implode(", ", $recursive)]));
continue;
}
if(!empty($bad)){
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.notFound", [$alias, implode(", ", $bad)]));
continue;
}
//These registered commands have absolute priority
if(count($targets) > 0){
$this->knownCommands[strtolower($alias)] = new FormattedCommandAlias(strtolower($alias), $targets);
}else{
unset($this->knownCommands[strtolower($alias)]);
}
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use function array_shift;
use function count;
use function implode;
class BanCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.ban.player.description",
"%commands.ban.usage"
);
$this->setPermission("pocketmine.command.ban.player");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$name = array_shift($args);
$reason = implode(" ", $args);
$sender->getServer()->getNameBans()->addBan($name, $reason, null, $sender->getName());
if(($player = $sender->getServer()->getPlayerExact($name)) instanceof Player){
$player->kick($reason !== "" ? "Banned by admin. Reason: " . $reason : "Banned by admin.");
}
Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.ban.success", [$player !== null ? $player->getName() : $name]));
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use function array_shift;
use function count;
use function implode;
use function preg_match;
class BanIpCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.ban.ip.description",
"%commands.banip.usage"
);
$this->setPermission("pocketmine.command.ban.ip");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$value = array_shift($args);
$reason = implode(" ", $args);
if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $value)){
$this->processIPBan($value, $sender, $reason);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success", [$value]));
}else{
if(($player = $sender->getServer()->getPlayer($value)) instanceof Player){
$ip = $player->getNetworkSession()->getIp();
$this->processIPBan($ip, $sender, $reason);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success.players", [$ip, $player->getName()]));
}else{
$sender->sendMessage(new TranslationContainer("commands.banip.invalid"));
return false;
}
}
return true;
}
private function processIPBan(string $ip, CommandSender $sender, string $reason) : void{
$sender->getServer()->getIPBans()->addBan($ip, $reason, null, $sender->getName());
foreach($sender->getServer()->getOnlinePlayers() as $player){
if($player->getNetworkSession()->getIp() === $ip){
$player->kick($reason !== "" ? $reason : "IP banned.");
}
}
$sender->getServer()->getNetwork()->blockAddress($ip, -1);
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\permission\BanEntry;
use function array_map;
use function count;
use function implode;
use function strtolower;
class BanListCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.banlist.description",
"%commands.banlist.usage"
);
$this->setPermission("pocketmine.command.ban.list");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(isset($args[0])){
$args[0] = strtolower($args[0]);
if($args[0] === "ips"){
$list = $sender->getServer()->getIPBans();
}elseif($args[0] === "players"){
$list = $sender->getServer()->getNameBans();
}else{
throw new InvalidCommandSyntaxException();
}
}else{
$list = $sender->getServer()->getNameBans();
$args[0] = "players";
}
$list = $list->getEntries();
$message = implode(", ", array_map(function(BanEntry $entry){
return $entry->getName();
}, $list));
if($args[0] === "ips"){
$sender->sendMessage(new TranslationContainer("commands.banlist.ips", [count($list)]));
}else{
$sender->sendMessage(new TranslationContainer("commands.banlist.players", [count($list)]));
}
$sender->sendMessage($message);
return true;
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\GameMode;
use function count;
class DefaultGamemodeCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.defaultgamemode.description",
"%commands.defaultgamemode.usage"
);
$this->setPermission("pocketmine.command.defaultgamemode");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
try{
$gameMode = GameMode::fromString($args[0]);
}catch(\InvalidArgumentException $e){
$sender->sendMessage("Unknown game mode");
return true;
}
$sender->getServer()->setConfigInt("gamemode", $gameMode->getMagicNumber());
$sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [$gameMode->getTranslationKey()]));
return true;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
class DeopCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.deop.description",
"%commands.deop.usage"
);
$this->setPermission("pocketmine.command.op.take");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$name = array_shift($args);
if(!Player::isValidUserName($name)){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getOfflinePlayer($name);
$player->setOp(false);
if($player instanceof Player){
$player->sendMessage(TextFormat::GRAY . "You are no longer op!");
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.deop.success", [$player->getName()]));
return true;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\world\World;
use function count;
class DifficultyCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.difficulty.description",
"%commands.difficulty.usage"
);
$this->setPermission("pocketmine.command.difficulty");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) !== 1){
throw new InvalidCommandSyntaxException();
}
$difficulty = World::getDifficultyFromString($args[0]);
if($sender->getServer()->isHardcore()){
$difficulty = World::DIFFICULTY_HARD;
}
if($difficulty !== -1){
$sender->getServer()->setConfigInt("difficulty", $difficulty);
//TODO: add per-world support
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->setDifficulty($difficulty);
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.difficulty.success", [$difficulty]));
}else{
throw new InvalidCommandSyntaxException();
}
return true;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use function date;
class DumpMemoryCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"Dumps the memory",
"/$name [path]"
);
$this->setPermission("pocketmine.command.dumpmemory");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? ($sender->getServer()->getDataPath() . "/memory_dumps/" . date("D_M_j-H.i.s-T_Y")), 48, 80);
return true;
}
}

View File

@@ -0,0 +1,125 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\entity\effect\EffectInstance;
use pocketmine\entity\effect\VanillaEffects;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function count;
use function strtolower;
use const INT32_MAX;
class EffectCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.effect.description",
"%commands.effect.usage"
);
$this->setPermission("pocketmine.command.effect");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
$effectManager = $player->getEffects();
if(strtolower($args[1]) === "clear"){
$effectManager->clear();
$sender->sendMessage(new TranslationContainer("commands.effect.success.removed.all", [$player->getDisplayName()]));
return true;
}
try{
$effect = VanillaEffects::fromString($args[1]);
}catch(\InvalidArgumentException $e){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [(string) $args[1]]));
return true;
}
$amplification = 0;
if(count($args) >= 3){
if(($d = $this->getBoundedInt($sender, $args[2], 0, (int) (INT32_MAX / 20))) === null){
return false;
}
$duration = $d * 20; //ticks
}else{
$duration = null;
}
if(count($args) >= 4){
$amplification = $this->getBoundedInt($sender, $args[3], 0, 255);
if($amplification === null){
return false;
}
}
$visible = true;
if(count($args) >= 5){
$v = strtolower($args[4]);
if($v === "on" or $v === "true" or $v === "t" or $v === "1"){
$visible = false;
}
}
if($duration === 0){
if(!$effectManager->has($effect)){
if(count($effectManager->all()) === 0){
$sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive.all", [$player->getDisplayName()]));
}else{
$sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive", [$effect->getName(), $player->getDisplayName()]));
}
return true;
}
$effectManager->remove($effect);
$sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()]));
}else{
$instance = new EffectInstance($effect, $duration, $amplification, $visible);
$effectManager->add($instance);
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20]));
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function count;
use function is_numeric;
class EnchantCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.enchant.description",
"%commands.enchant.usage"
);
$this->setPermission("pocketmine.command.enchant");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
$item = $player->getInventory()->getItemInHand();
if($item->isNull()){
$sender->sendMessage(new TranslationContainer("commands.enchant.noItem"));
return true;
}
if(is_numeric($args[1])){
$enchantment = Enchantment::get((int) $args[1]);
}else{
$enchantment = Enchantment::fromString($args[1]);
}
if(!($enchantment instanceof Enchantment)){
$sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]]));
return true;
}
$level = 1;
if(isset($args[2])){
$level = $this->getBoundedInt($sender, $args[2], 1, $enchantment->getMaxLevel());
if($level === null){
return false;
}
}
$item->addEnchantment(new EnchantmentInstance($enchantment, $level));
$player->getInventory()->setItemInHand($item);
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success", [$player->getName()]));
return true;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\GameMode;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
class GamemodeCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.gamemode.description",
"%commands.gamemode.usage"
);
$this->setPermission("pocketmine.command.gamemode");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
try{
$gameMode = GameMode::fromString($args[0]);
}catch(\InvalidArgumentException $e){
$sender->sendMessage("Unknown game mode");
return true;
}
$target = $sender;
if(isset($args[1])){
$target = $sender->getServer()->getPlayer($args[1]);
if($target === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
}elseif(!($sender instanceof Player)){
throw new InvalidCommandSyntaxException();
}
$target->setGamemode($gameMode);
if(!$gameMode->equals($target->getGamemode())){
$sender->sendMessage("Game mode change for " . $target->getName() . " failed!");
}else{
if($target === $sender){
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [$gameMode->getTranslationKey()]));
}else{
$target->sendMessage(new TranslationContainer("gameMode.changed", [$gameMode->getTranslationKey()]));
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [$gameMode->getTranslationKey(), $target->getName()]));
}
}
return true;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use function count;
use function memory_get_usage;
use function number_format;
use function round;
class GarbageCollectorCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.gc.description",
"%pocketmine.command.gc.usage"
);
$this->setPermission("pocketmine.command.gc");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$chunksCollected = 0;
$entitiesCollected = 0;
$memory = memory_get_usage();
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$diff = [count($world->getChunks()), count($world->getEntities())];
$world->doChunkGarbageCollection();
$world->unloadChunks(true);
$chunksCollected += $diff[0] - count($world->getChunks());
$entitiesCollected += $diff[1] - count($world->getEntities());
$world->clearCache(true);
}
$cyclesCollected = $sender->getServer()->getMemoryManager()->triggerGarbageCollector();
$sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Garbage collection result" . TextFormat::GREEN . " ----");
$sender->sendMessage(TextFormat::GOLD . "Chunks: " . TextFormat::RED . number_format($chunksCollected));
$sender->sendMessage(TextFormat::GOLD . "Entities: " . TextFormat::RED . number_format($entitiesCollected));
$sender->sendMessage(TextFormat::GOLD . "Cycles: " . TextFormat::RED . number_format($cyclesCollected));
$sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB");
return true;
}
}

View File

@@ -0,0 +1,99 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\item\ItemFactory;
use pocketmine\lang\TranslationContainer;
use pocketmine\nbt\JsonNbtParser;
use pocketmine\nbt\NbtDataException;
use pocketmine\utils\TextFormat;
use function array_slice;
use function count;
use function implode;
class GiveCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.give.description",
"%pocketmine.command.give.usage"
);
$this->setPermission("pocketmine.command.give");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
try{
$item = ItemFactory::fromString($args[1]);
}catch(\InvalidArgumentException $e){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]]));
return true;
}
if(!isset($args[2])){
$item->setCount($item->getMaxStackSize());
}else{
$item->setCount((int) $args[2]);
}
if(isset($args[3])){
$data = implode(" ", array_slice($args, 3));
try{
$tags = JsonNbtParser::parseJson($data);
}catch(NbtDataException $e){
$sender->sendMessage(new TranslationContainer("commands.give.tagError", [$e->getMessage()]));
return true;
}
$item->setNamedTag($tags);
}
//TODO: overflow
$player->getInventory()->addItem(clone $item);
Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.give.success", [
$item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")",
(string) $item->getCount(),
$player->getName()
]));
return true;
}
}

View File

@@ -0,0 +1,113 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function array_chunk;
use function array_pop;
use function count;
use function explode;
use function implode;
use function is_numeric;
use function ksort;
use function min;
use function strtolower;
use const SORT_FLAG_CASE;
use const SORT_NATURAL;
class HelpCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.help.description",
"%commands.help.usage",
["?"]
);
$this->setPermission("pocketmine.command.help");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
$command = "";
$pageNumber = 1;
}elseif(is_numeric($args[count($args) - 1])){
$pageNumber = (int) array_pop($args);
if($pageNumber <= 0){
$pageNumber = 1;
}
$command = implode(" ", $args);
}else{
$command = implode(" ", $args);
$pageNumber = 1;
}
$pageHeight = $sender->getScreenLineHeight();
if($command === ""){
/** @var Command[][] $commands */
$commands = [];
foreach($sender->getServer()->getCommandMap()->getCommands() as $command){
if($command->testPermissionSilent($sender)){
$commands[$command->getName()] = $command;
}
}
ksort($commands, SORT_NATURAL | SORT_FLAG_CASE);
$commands = array_chunk($commands, $pageHeight);
$pageNumber = (int) min(count($commands), $pageNumber);
if($pageNumber < 1){
$pageNumber = 1;
}
$sender->sendMessage(new TranslationContainer("commands.help.header", [$pageNumber, count($commands)]));
if(isset($commands[$pageNumber - 1])){
foreach($commands[$pageNumber - 1] as $command){
$sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $command->getDescription());
}
}
return true;
}else{
if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($command))) instanceof Command){
if($cmd->testPermissionSilent($sender)){
$message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n";
$message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $cmd->getDescription() . "\n";
$message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $cmd->getUsage())) . "\n";
$sender->sendMessage($message);
return true;
}
}
$sender->sendMessage(TextFormat::RED . "No help for " . strtolower($command));
return true;
}
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
use function implode;
use function trim;
class KickCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.kick.description",
"%commands.kick.usage"
);
$this->setPermission("pocketmine.command.kick");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$name = array_shift($args);
$reason = trim(implode(" ", $args));
if(($player = $sender->getServer()->getPlayer($name)) instanceof Player){
$player->kick($reason);
if($reason !== ""){
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success.reason", [$player->getName(), $reason]));
}else{
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success", [$player->getName()]));
}
}else{
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
}
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
class KillCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.kill.description",
"%pocketmine.command.kill.usage",
["suicide"]
);
$this->setPermission("pocketmine.command.kill.self;pocketmine.command.kill.other");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) >= 2){
throw new InvalidCommandSyntaxException();
}
if(count($args) === 1){
if(!$sender->hasPermission("pocketmine.command.kill.other")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player instanceof Player){
$player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000));
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kill.successful", [$player->getName()]));
}else{
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
}
return true;
}
if($sender instanceof Player){
if(!$sender->hasPermission("pocketmine.command.kill.self")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
$sender->attack(new EntityDamageEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000));
$sender->sendMessage(new TranslationContainer("commands.kill.successful", [$sender->getName()]));
}else{
throw new InvalidCommandSyntaxException();
}
return true;
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use function array_filter;
use function array_map;
use function count;
use function implode;
class ListCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.list.description",
"%command.players.usage"
);
$this->setPermission("pocketmine.command.list");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$playerNames = array_map(function(Player $player){
return $player->getName();
}, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender){
return !($sender instanceof Player) or $sender->canSee($player);
}));
$sender->sendMessage(new TranslationContainer("commands.players.list", [count($playerNames), $sender->getServer()->getMaxPlayers()]));
$sender->sendMessage(implode(", ", $playerNames));
return true;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
class MeCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.me.description",
"%commands.me.usage"
);
$this->setPermission("pocketmine.command.me");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$sender->getServer()->broadcastMessage(new TranslationContainer("chat.type.emote", [$sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args)]));
return true;
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
class OpCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.op.description",
"%commands.op.usage"
);
$this->setPermission("pocketmine.command.op.give");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$name = array_shift($args);
if(!Player::isValidUserName($name)){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getOfflinePlayer($name);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.op.success", [$player->getName()]));
if($player instanceof Player){
$player->sendMessage(TextFormat::GRAY . "You are now op!");
}
$player->setOp(true);
return true;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function count;
class PardonCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.unban.player.description",
"%commands.unban.usage",
["unban"]
);
$this->setPermission("pocketmine.command.unban.player");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) !== 1){
throw new InvalidCommandSyntaxException();
}
$sender->getServer()->getNameBans()->remove($args[0]);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.unban.success", [$args[0]]));
return true;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function count;
use function preg_match;
class PardonIpCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.unban.ip.description",
"%commands.unbanip.usage",
["unban-ip"]
);
$this->setPermission("pocketmine.command.unban.ip");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) !== 1){
throw new InvalidCommandSyntaxException();
}
if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $args[0])){
$sender->getServer()->getIPBans()->remove($args[0]);
$sender->getServer()->getNetwork()->unblockAddress($args[0]);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.unbanip.success", [$args[0]]));
}else{
$sender->sendMessage(new TranslationContainer("commands.unbanip.invalid"));
}
return true;
}
}

View File

@@ -0,0 +1,232 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\block\BlockFactory;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\item\ItemFactory;
use pocketmine\item\VanillaItems;
use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\utils\Random;
use pocketmine\utils\TextFormat;
use pocketmine\world\particle\AngryVillagerParticle;
use pocketmine\world\particle\BlockForceFieldParticle;
use pocketmine\world\particle\BubbleParticle;
use pocketmine\world\particle\CriticalParticle;
use pocketmine\world\particle\DustParticle;
use pocketmine\world\particle\EnchantmentTableParticle;
use pocketmine\world\particle\EnchantParticle;
use pocketmine\world\particle\ExplodeParticle;
use pocketmine\world\particle\FlameParticle;
use pocketmine\world\particle\HappyVillagerParticle;
use pocketmine\world\particle\HeartParticle;
use pocketmine\world\particle\HugeExplodeParticle;
use pocketmine\world\particle\HugeExplodeSeedParticle;
use pocketmine\world\particle\InkParticle;
use pocketmine\world\particle\InstantEnchantParticle;
use pocketmine\world\particle\ItemBreakParticle;
use pocketmine\world\particle\LavaDripParticle;
use pocketmine\world\particle\LavaParticle;
use pocketmine\world\particle\Particle;
use pocketmine\world\particle\PortalParticle;
use pocketmine\world\particle\RainSplashParticle;
use pocketmine\world\particle\RedstoneParticle;
use pocketmine\world\particle\SmokeParticle;
use pocketmine\world\particle\SplashParticle;
use pocketmine\world\particle\SporeParticle;
use pocketmine\world\particle\TerrainParticle;
use pocketmine\world\particle\WaterDripParticle;
use pocketmine\world\particle\WaterParticle;
use pocketmine\world\World;
use function count;
use function explode;
use function max;
use function microtime;
use function mt_rand;
use function strpos;
use function strtolower;
class ParticleCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.particle.description",
"%pocketmine.command.particle.usage"
);
$this->setPermission("pocketmine.command.particle");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 7){
throw new InvalidCommandSyntaxException();
}
if($sender instanceof Player){
$world = $sender->getWorld();
$pos = new Vector3(
$this->getRelativeDouble($sender->getX(), $sender, $args[1]),
$this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, World::Y_MAX),
$this->getRelativeDouble($sender->getZ(), $sender, $args[3])
);
}else{
$world = $sender->getServer()->getWorldManager()->getDefaultWorld();
$pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]);
}
$name = strtolower($args[0]);
$xd = (float) $args[4];
$yd = (float) $args[5];
$zd = (float) $args[6];
$count = isset($args[7]) ? max(1, (int) $args[7]) : 1;
$data = isset($args[8]) ? (int) $args[8] : null;
$particle = $this->getParticle($name, $data);
if($particle === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.particle.notFound", [$name]));
return true;
}
$sender->sendMessage(new TranslationContainer("commands.particle.success", [$name, $count]));
$random = new Random((int) (microtime(true) * 1000) + mt_rand());
for($i = 0; $i < $count; ++$i){
$world->addParticle($pos->add(
$random->nextSignedFloat() * $xd,
$random->nextSignedFloat() * $yd,
$random->nextSignedFloat() * $zd
), $particle);
}
return true;
}
/**
* @param string $name
* @param int|null $data
*
* @return Particle|null
*/
private function getParticle(string $name, ?int $data = null) : ?Particle{
switch($name){
case "explode":
return new ExplodeParticle();
case "hugeexplosion":
return new HugeExplodeParticle();
case "hugeexplosionseed":
return new HugeExplodeSeedParticle();
case "bubble":
return new BubbleParticle();
case "splash":
return new SplashParticle();
case "wake":
case "water":
return new WaterParticle();
case "crit":
return new CriticalParticle();
case "smoke":
return new SmokeParticle($data ?? 0);
case "spell":
return new EnchantParticle();
case "instantspell":
return new InstantEnchantParticle();
case "dripwater":
return new WaterDripParticle();
case "driplava":
return new LavaDripParticle();
case "townaura":
case "spore":
return new SporeParticle();
case "portal":
return new PortalParticle();
case "flame":
return new FlameParticle();
case "lava":
return new LavaParticle();
case "reddust":
return new RedstoneParticle($data ?? 1);
case "snowballpoof":
return new ItemBreakParticle(VanillaItems::SNOWBALL());
case "slime":
return new ItemBreakParticle(VanillaItems::SLIMEBALL());
case "itembreak":
if($data !== null and $data !== 0){
return new ItemBreakParticle(ItemFactory::get($data));
}
break;
case "terrain":
if($data !== null and $data !== 0){
return new TerrainParticle(BlockFactory::get($data));
}
break;
case "heart":
return new HeartParticle($data ?? 0);
case "ink":
return new InkParticle($data ?? 0);
case "droplet":
return new RainSplashParticle();
case "enchantmenttable":
return new EnchantmentTableParticle();
case "happyvillager":
return new HappyVillagerParticle();
case "angryvillager":
return new AngryVillagerParticle();
case "forcefield":
return new BlockForceFieldParticle($data ?? 0);
}
if(strpos($name, "iconcrack_") === 0){
$d = explode("_", $name);
if(count($d) === 3){
return new ItemBreakParticle(ItemFactory::get((int) $d[1], (int) $d[2]));
}
}elseif(strpos($name, "blockcrack_") === 0){
$d = explode("_", $name);
if(count($d) === 2){
return new TerrainParticle(BlockFactory::get(((int) $d[1]) & 0xff, ((int) $d[1]) >> 12));
}
}elseif(strpos($name, "blockdust_") === 0){
$d = explode("_", $name);
if(count($d) >= 4){
return new DustParticle(((int) $d[1]) & 0xff, ((int) $d[2]) & 0xff, ((int) $d[3]) & 0xff, isset($d[4]) ? ((int) $d[4]) & 0xff : 255);
}
}
return null;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\plugin\Plugin;
use pocketmine\utils\TextFormat;
use function array_map;
use function count;
use function implode;
class PluginsCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.plugins.description",
"%pocketmine.command.plugins.usage",
["pl"]
);
$this->setPermission("pocketmine.command.plugins");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$list = array_map(function(Plugin $plugin) : string{
return ($plugin->isEnabled() ? TextFormat::GREEN : TextFormat::RED) . $plugin->getDescription()->getFullName();
}, $sender->getServer()->getPluginManager()->getPlugins());
$sender->sendMessage(new TranslationContainer("pocketmine.command.plugins.success", [count($list), implode(TextFormat::WHITE . ", ", $list)]));
return true;
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use function microtime;
use function round;
class SaveCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.save.description",
"%commands.save.usage"
);
$this->setPermission("pocketmine.command.save.perform");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.start"));
$start = microtime(true);
foreach($sender->getServer()->getOnlinePlayers() as $player){
$player->save();
}
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->save(true);
}
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.success", [round(microtime(true) - $start, 3)]));
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
class SaveOffCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.saveoff.description",
"%commands.save-off.usage"
);
$this->setPermission("pocketmine.command.save.disable");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$sender->getServer()->getWorldManager()->setAutoSave(false);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.disabled"));
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
class SaveOnCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.saveon.description",
"%commands.save-on.usage"
);
$this->setPermission("pocketmine.command.save.enable");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$sender->getServer()->getWorldManager()->setAutoSave(true);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.enabled"));
return true;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\ConsoleCommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
class SayCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.say.description",
"%commands.say.usage"
);
$this->setPermission("pocketmine.command.say");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
throw new InvalidCommandSyntaxException();
}
$sender->getServer()->broadcastMessage(new TranslationContainer(TextFormat::LIGHT_PURPLE . "%chat.type.announcement", [$sender instanceof Player ? $sender->getDisplayName() : ($sender instanceof ConsoleCommandSender ? "Server" : $sender->getName()), TextFormat::LIGHT_PURPLE . implode(" ", $args)]));
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
class SeedCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.seed.description",
"%commands.seed.usage"
);
$this->setPermission("pocketmine.command.seed");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if($sender instanceof Player){
$seed = $sender->getWorld()->getSeed();
}else{
$seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed();
}
$sender->sendMessage(new TranslationContainer("commands.seed.success", [$seed]));
return true;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
use function round;
class SetWorldSpawnCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.setworldspawn.description",
"%commands.setworldspawn.usage"
);
$this->setPermission("pocketmine.command.setworldspawn");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
if($sender instanceof Player){
$world = $sender->getWorld();
$pos = (new Vector3($sender->x, $sender->y, $sender->z))->round();
}else{
$sender->sendMessage(TextFormat::RED . "You can only perform this command as a player");
return true;
}
}elseif(count($args) === 3){
$world = $sender->getServer()->getWorldManager()->getDefaultWorld();
$pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2]));
}else{
throw new InvalidCommandSyntaxException();
}
$world->setSpawnLocation($pos);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.setworldspawn.success", [round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)]));
return true;
}
}

View File

@@ -0,0 +1,101 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use pocketmine\world\Position;
use pocketmine\world\World;
use function count;
use function round;
class SpawnpointCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.spawnpoint.description",
"%commands.spawnpoint.usage"
);
$this->setPermission("pocketmine.command.spawnpoint");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$target = null;
if(count($args) === 0){
if($sender instanceof Player){
$target = $sender;
}else{
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
return true;
}
}else{
$target = $sender->getServer()->getPlayer($args[0]);
if($target === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
}
if(count($args) === 4){
if($target->isValid()){
$world = $target->getWorld();
$pos = $sender instanceof Player ? $sender->getPosition() : $world->getSpawnLocation();
$x = $this->getRelativeDouble($pos->x, $sender, $args[1]);
$y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, World::Y_MAX);
$z = $this->getRelativeDouble($pos->z, $sender, $args[3]);
$target->setSpawn(new Position($x, $y, $z, $world));
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)]));
return true;
}
}elseif(count($args) <= 1){
if($sender instanceof Player){
$pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getWorld());
$target->setSpawn($pos);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)]));
return true;
}else{
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
return true;
}
}
throw new InvalidCommandSyntaxException();
}
}

View File

@@ -0,0 +1,122 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\utils\Process;
use pocketmine\utils\TextFormat;
use function count;
use function floor;
use function microtime;
use function number_format;
use function round;
class StatusCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.status.description",
"%pocketmine.command.status.usage"
);
$this->setPermission("pocketmine.command.status");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$rUsage = Process::getRealMemoryUsage();
$mUsage = Process::getMemoryUsage(true);
$server = $sender->getServer();
$sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----");
$time = microtime(true) - \pocketmine\START_TIME;
$seconds = floor($time % 60);
$minutes = null;
$hours = null;
$days = null;
if($time >= 60){
$minutes = floor(($time % 3600) / 60);
if($time >= 3600){
$hours = floor(($time % (3600 * 24)) / 3600);
if($time >= 3600 * 24){
$days = floor($time / (3600 * 24));
}
}
}
$uptime = ($minutes !== null ?
($hours !== null ?
($days !== null ?
"$days days "
: "") . "$hours hours "
: "") . "$minutes minutes "
: "") . "$seconds seconds";
$sender->sendMessage(TextFormat::GOLD . "Uptime: " . TextFormat::RED . $uptime);
$tpsColor = TextFormat::GREEN;
if($server->getTicksPerSecond() < 17){
$tpsColor = TextFormat::GOLD;
}elseif($server->getTicksPerSecond() < 12){
$tpsColor = TextFormat::RED;
}
$sender->sendMessage(TextFormat::GOLD . "Current TPS: {$tpsColor}{$server->getTicksPerSecond()} ({$server->getTickUsage()}%)");
$sender->sendMessage(TextFormat::GOLD . "Average TPS: {$tpsColor}{$server->getTicksPerSecondAverage()} ({$server->getTickUsageAverage()}%)");
$sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($server->getNetwork()->getUpload() / 1024, 2) . " kB/s");
$sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($server->getNetwork()->getDownload() / 1024, 2) . " kB/s");
$sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Process::getThreadCount());
$sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
$globalLimit = $server->getMemoryManager()->getGlobalMemoryLimit();
if($globalLimit > 0){
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($globalLimit, 2), 2) . " MB.");
}
foreach($server->getWorldManager()->getWorlds() as $world){
$worldName = $world->getFolderName() !== $world->getDisplayName() ? " (" . $world->getDisplayName() . ")" : "";
$timeColor = $world->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW;
$sender->sendMessage(TextFormat::GOLD . "World \"{$world->getFolderName()}\"$worldName: " .
TextFormat::RED . number_format(count($world->getChunks())) . TextFormat::GREEN . " chunks, " .
TextFormat::RED . number_format(count($world->getEntities())) . TextFormat::GREEN . " entities. " .
"Time $timeColor" . round($world->getTickRateTime(), 2) . "ms"
);
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
class StopCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.stop.description",
"%commands.stop.usage"
);
$this->setPermission("pocketmine.command.stop");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.stop.start"));
$sender->getServer()->shutdown();
return true;
}
}

View File

@@ -0,0 +1,130 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function array_filter;
use function array_values;
use function count;
use function round;
class TeleportCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.tp.description",
"%commands.tp.usage",
["teleport"]
);
$this->setPermission("pocketmine.command.teleport");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$args = array_values(array_filter($args, function($arg){
return $arg !== "";
}));
if(count($args) < 1 or count($args) > 6){
throw new InvalidCommandSyntaxException();
}
$target = null;
$origin = $sender;
if(count($args) === 1 or count($args) === 3){
if($sender instanceof Player){
$target = $sender;
}else{
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
return true;
}
if(count($args) === 1){
$target = $sender->getServer()->getPlayer($args[0]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
return true;
}
}
}else{
$target = $sender->getServer()->getPlayer($args[0]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
return true;
}
if(count($args) === 2){
$origin = $target;
$target = $sender->getServer()->getPlayer($args[1]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[1]);
return true;
}
}
}
if(count($args) < 3){
$origin->teleport($target);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()]));
return true;
}elseif($target->isValid()){
if(count($args) === 4 or count($args) === 6){
$pos = 1;
}else{
$pos = 0;
}
$x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]);
$y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 256);
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos++]);
$yaw = $target->getYaw();
$pitch = $target->getPitch();
if(count($args) === 6 or (count($args) === 5 and $pos === 3)){
$yaw = (float) $args[$pos++];
$pitch = (float) $args[$pos++];
}
$target->teleport(new Vector3($x, $y, $z), $yaw, $pitch);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success.coordinates", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)]));
return true;
}
throw new InvalidCommandSyntaxException();
}
}

View File

@@ -0,0 +1,76 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
use function implode;
class TellCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.tell.description",
"%commands.message.usage",
["w", "msg"]
);
$this->setPermission("pocketmine.command.tell");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getPlayer(array_shift($args));
if($player === $sender){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.message.sameTarget"));
return true;
}
if($player instanceof Player){
$message = implode(" ", $args);
$sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.outgoing", [$player->getDisplayName(), $message]));
$name = $sender instanceof Player ? $sender->getDisplayName() : $sender->getName();
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.incoming", [$name, $message]));
Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.message.display.outgoing", [$player->getDisplayName(), $message]), false);
}else{
$sender->sendMessage(new TranslationContainer("commands.generic.player.notFound"));
}
return true;
}
}

View File

@@ -0,0 +1,130 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use pocketmine\world\World;
use function count;
class TimeCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.time.description",
"%pocketmine.command.time.usage"
);
$this->setPermission("pocketmine.command.time.add;pocketmine.command.time.set;pocketmine.command.time.start;pocketmine.command.time.stop");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(count($args) < 1){
throw new InvalidCommandSyntaxException();
}
if($args[0] === "start"){
if(!$sender->hasPermission("pocketmine.command.time.start")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->startTime();
}
Command::broadcastCommandMessage($sender, "Restarted the time");
return true;
}elseif($args[0] === "stop"){
if(!$sender->hasPermission("pocketmine.command.time.stop")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->stopTime();
}
Command::broadcastCommandMessage($sender, "Stopped the time");
return true;
}elseif($args[0] === "query"){
if(!$sender->hasPermission("pocketmine.command.time.query")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
if($sender instanceof Player){
$world = $sender->getWorld();
}else{
$world = $sender->getServer()->getWorldManager()->getDefaultWorld();
}
$sender->sendMessage($sender->getServer()->getLanguage()->translateString("commands.time.query", [$world->getTime()]));
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
if($args[0] === "set"){
if(!$sender->hasPermission("pocketmine.command.time.set")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
if($args[1] === "day"){
$value = World::TIME_DAY;
}elseif($args[1] === "night"){
$value = World::TIME_NIGHT;
}else{
$value = $this->getInteger($sender, $args[1], 0);
}
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->setTime($value);
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value]));
}elseif($args[0] === "add"){
if(!$sender->hasPermission("pocketmine.command.time.add")){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
$value = $this->getInteger($sender, $args[1], 0);
foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){
$world->setTime($world->getTime() + $value);
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value]));
}else{
throw new InvalidCommandSyntaxException();
}
return true;
}
}

View File

@@ -0,0 +1,174 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\scheduler\BulkCurlTask;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\InternetException;
use function count;
use function fclose;
use function file_exists;
use function fopen;
use function fseek;
use function http_build_query;
use function is_array;
use function json_decode;
use function mkdir;
use function stream_get_contents;
use function strtolower;
use const CURLOPT_AUTOREFERER;
use const CURLOPT_FOLLOWLOCATION;
use const CURLOPT_HTTPHEADER;
use const CURLOPT_POST;
use const CURLOPT_POSTFIELDS;
class TimingsCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.timings.description",
"%pocketmine.command.timings.usage"
);
$this->setPermission("pocketmine.command.timings");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) !== 1){
throw new InvalidCommandSyntaxException();
}
$mode = strtolower($args[0]);
if($mode === "on"){
TimingsHandler::setEnabled();
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.enable"));
return true;
}elseif($mode === "off"){
TimingsHandler::setEnabled(false);
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.disable"));
return true;
}
if(!TimingsHandler::isEnabled()){
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsDisabled"));
return true;
}
$paste = $mode === "paste";
if($mode === "reset"){
TimingsHandler::reload();
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.reset"));
}elseif($mode === "merged" or $mode === "report" or $paste){
$timings = "";
if($paste){
$fileTimings = fopen("php://temp", "r+b");
}else{
$index = 0;
$timingFolder = $sender->getServer()->getDataPath() . "timings/";
if(!file_exists($timingFolder)){
mkdir($timingFolder, 0777);
}
$timings = $timingFolder . "timings.txt";
while(file_exists($timings)){
$timings = $timingFolder . "timings" . (++$index) . ".txt";
}
$fileTimings = fopen($timings, "a+b");
}
TimingsHandler::printTimings($fileTimings);
if($paste){
fseek($fileTimings, 0);
$data = [
"browser" => $agent = $sender->getServer()->getName() . " " . $sender->getServer()->getPocketMineVersion(),
"data" => $content = stream_get_contents($fileTimings)
];
fclose($fileTimings);
$host = $sender->getServer()->getProperty("timings.host", "timings.pmmp.io");
$sender->getServer()->getAsyncPool()->submitTask(new class($sender, $host, $agent, $data) extends BulkCurlTask{
private const TLS_KEY_SENDER = "sender";
/** @var string */
private $host;
public function __construct(CommandSender $sender, string $host, string $agent, array $data){
parent::__construct([
["page" => "https://$host?upload=true", "extraOpts" => [
CURLOPT_HTTPHEADER => [
"User-Agent: $agent",
"Content-Type: application/x-www-form-urlencoded"
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($data),
CURLOPT_AUTOREFERER => false,
CURLOPT_FOLLOWLOCATION => false
]]
]);
$this->host = $host;
$this->storeLocal(self::TLS_KEY_SENDER, $sender);
}
public function onCompletion() : void{
/** @var CommandSender $sender */
$sender = $this->fetchLocal(self::TLS_KEY_SENDER);
if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender
return;
}
$result = $this->getResult()[0];
if($result instanceof InternetException){
$sender->getServer()->getLogger()->logException($result);
return;
}
if(isset($result[0]) && is_array($response = json_decode($result[0], true)) && isset($response["id"])){
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsRead",
["https://" . $this->host . "/?id=" . $response["id"]]));
}else{
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.pasteError"));
}
}
});
}else{
fclose($fileTimings);
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsWrite", [$timings]));
}
}
return true;
}
}

View File

@@ -0,0 +1,102 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function array_slice;
use function count;
use function implode;
class TitleCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.title.description",
"%commands.title.usage"
);
$this->setPermission("pocketmine.command.title");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
throw new InvalidCommandSyntaxException();
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player === null){
$sender->sendMessage(new TranslationContainer("commands.generic.player.notFound"));
return true;
}
switch($args[1]){
case "clear":
$player->removeTitles();
break;
case "reset":
$player->resetTitles();
break;
case "title":
if(count($args) < 3){
throw new InvalidCommandSyntaxException();
}
$player->sendTitle(implode(" ", array_slice($args, 2)));
break;
case "subtitle":
if(count($args) < 3){
throw new InvalidCommandSyntaxException();
}
$player->sendSubTitle(implode(" ", array_slice($args, 2)));
break;
case "actionbar":
if(count($args) < 3){
throw new InvalidCommandSyntaxException();
}
$player->sendActionBarMessage(implode(" ", array_slice($args, 2)));
break;
case "times":
if(count($args) < 5){
throw new InvalidCommandSyntaxException();
}
$player->setTitleDuration($this->getInteger($sender, $args[2]), $this->getInteger($sender, $args[3]), $this->getInteger($sender, $args[4]));
break;
default:
throw new InvalidCommandSyntaxException();
}
$sender->sendMessage(new TranslationContainer("commands.title.success"));
return true;
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\player\Player;
use function count;
class TransferServerCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.transferserver.description",
"%pocketmine.command.transferserver.usage"
);
$this->setPermission("pocketmine.command.transferserver");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(count($args) < 1){
throw new InvalidCommandSyntaxException();
}elseif(!($sender instanceof Player)){
$sender->sendMessage("This command must be executed as a player");
return false;
}
$sender->transfer($args[0], (int) ($args[1] ?? 19132));
return true;
}
}

View File

@@ -0,0 +1,114 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function is_numeric;
use function substr;
abstract class VanillaCommand extends Command{
public const MAX_COORD = 30000000;
public const MIN_COORD = -30000000;
/**
* @param CommandSender $sender
* @param mixed $value
* @param int $min
* @param int $max
*
* @return int
*/
protected function getInteger(CommandSender $sender, $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{
$i = (int) $value;
if($i < $min){
$i = $min;
}elseif($i > $max){
$i = $max;
}
return $i;
}
/**
* @param float $original
* @param CommandSender $sender
* @param string $input
* @param float $min
* @param float $max
*
* @return float
*/
protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{
if($input[0] === "~"){
$value = $this->getDouble($sender, substr($input, 1));
return $original + $value;
}
return $this->getDouble($sender, $input, $min, $max);
}
/**
* @param CommandSender $sender
* @param mixed $value
* @param float $min
* @param float $max
*
* @return float
*/
protected function getDouble(CommandSender $sender, $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{
$i = (double) $value;
if($i < $min){
$i = $min;
}elseif($i > $max){
$i = $max;
}
return $i;
}
protected function getBoundedInt(CommandSender $sender, string $input, int $min, int $max) : ?int{
if(!is_numeric($input)){
throw new InvalidCommandSyntaxException();
}
$v = (int) $input;
if($v > $max){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooBig", [$input, (string) $max]));
return null;
}
if($v < $min){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooSmall", [$input, (string) $min]));
return null;
}
return $v;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\plugin\Plugin;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
use function stripos;
use function strtolower;
class VersionCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.version.description",
"%pocketmine.command.version.usage",
["ver", "about"]
);
$this->setPermission("pocketmine.command.version");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
$sender->sendMessage(new TranslationContainer("pocketmine.server.info.extended", [
$sender->getServer()->getName(),
$sender->getServer()->getPocketMineVersion(),
$sender->getServer()->getVersion(),
ProtocolInfo::CURRENT_PROTOCOL
]));
}else{
$pluginName = implode(" ", $args);
$exactPlugin = $sender->getServer()->getPluginManager()->getPlugin($pluginName);
if($exactPlugin instanceof Plugin){
$this->describeToSender($exactPlugin, $sender);
return true;
}
$found = false;
$pluginName = strtolower($pluginName);
foreach($sender->getServer()->getPluginManager()->getPlugins() as $plugin){
if(stripos($plugin->getName(), $pluginName) !== false){
$this->describeToSender($plugin, $sender);
$found = true;
}
}
if(!$found){
$sender->sendMessage(new TranslationContainer("pocketmine.command.version.noSuchPlugin"));
}
}
return true;
}
private function describeToSender(Plugin $plugin, CommandSender $sender) : void{
$desc = $plugin->getDescription();
$sender->sendMessage(TextFormat::DARK_GREEN . $desc->getName() . TextFormat::WHITE . " version " . TextFormat::DARK_GREEN . $desc->getVersion());
if($desc->getDescription() !== ""){
$sender->sendMessage($desc->getDescription());
}
if($desc->getWebsite() !== ""){
$sender->sendMessage("Website: " . $desc->getWebsite());
}
if(count($authors = $desc->getAuthors()) > 0){
if(count($authors) === 1){
$sender->sendMessage("Author: " . implode(", ", $authors));
}else{
$sender->sendMessage("Authors: " . implode(", ", $authors));
}
}
}
}

View File

@@ -0,0 +1,131 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
use function strtolower;
class WhitelistCommand extends VanillaCommand{
public function __construct(string $name){
parent::__construct(
$name,
"%pocketmine.command.whitelist.description",
"%commands.whitelist.usage"
);
$this->setPermission("pocketmine.command.whitelist.reload;pocketmine.command.whitelist.enable;pocketmine.command.whitelist.disable;pocketmine.command.whitelist.list;pocketmine.command.whitelist.add;pocketmine.command.whitelist.remove");
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0 or count($args) > 2){
throw new InvalidCommandSyntaxException();
}
if(count($args) === 1){
if($this->badPerm($sender, strtolower($args[0]))){
return false;
}
switch(strtolower($args[0])){
case "reload":
$sender->getServer()->getWhitelisted()->reload();
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.reloaded"));
return true;
case "on":
$sender->getServer()->setConfigBool("white-list", true);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.enabled"));
return true;
case "off":
$sender->getServer()->setConfigBool("white-list", false);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.disabled"));
return true;
case "list":
$entries = $sender->getServer()->getWhitelisted()->getAll(true);
$result = implode($entries, ", ");
$count = count($entries);
$sender->sendMessage(new TranslationContainer("commands.whitelist.list", [$count, $count]));
$sender->sendMessage($result);
return true;
case "add":
$sender->sendMessage(new TranslationContainer("commands.generic.usage", ["%commands.whitelist.add.usage"]));
return true;
case "remove":
$sender->sendMessage(new TranslationContainer("commands.generic.usage", ["%commands.whitelist.remove.usage"]));
return true;
}
}elseif(count($args) === 2){
if($this->badPerm($sender, strtolower($args[0]))){
return false;
}
if(!Player::isValidUserName($args[1])){
throw new InvalidCommandSyntaxException();
}
switch(strtolower($args[0])){
case "add":
$sender->getServer()->getOfflinePlayer($args[1])->setWhitelisted(true);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.add.success", [$args[1]]));
return true;
case "remove":
$sender->getServer()->getOfflinePlayer($args[1])->setWhitelisted(false);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.remove.success", [$args[1]]));
return true;
}
}
return true;
}
private function badPerm(CommandSender $sender, string $subcommand) : bool{
static $map = [
"on" => "enable",
"off" => "disable"
];
if(!$sender->hasPermission("pocketmine.command.whitelist." . ($map[$subcommand] ?? $subcommand))){
$sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission"));
return true;
}
return false;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\utils;
class CommandException extends \RuntimeException{
}

View File

@@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\command\utils;
class InvalidCommandSyntaxException extends CommandException{
}