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

194
src/permission/BanEntry.php Normal file
View File

@@ -0,0 +1,194 @@
<?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\permission;
use function array_shift;
use function explode;
use function implode;
use function strlen;
use function strtolower;
use function trim;
class BanEntry{
/**
* @var string
*/
public static $format = "Y-m-d H:i:s O";
/** @var string */
private $name;
/** @var \DateTime */
private $creationDate = null;
/** @var string */
private $source = "(Unknown)";
/** @var \DateTime|null */
private $expirationDate = null;
/** @var string */
private $reason = "Banned by an operator.";
public function __construct(string $name){
$this->name = strtolower($name);
/** @noinspection PhpUnhandledExceptionInspection */
$this->creationDate = new \DateTime();
}
public function getName() : string{
return $this->name;
}
public function getCreated() : \DateTime{
return $this->creationDate;
}
/**
* @param \DateTime $date
*
* @throws \InvalidArgumentException
*/
public function setCreated(\DateTime $date) : void{
self::validateDate($date);
$this->creationDate = $date;
}
public function getSource() : string{
return $this->source;
}
public function setSource(string $source) : void{
$this->source = $source;
}
/**
* @return \DateTime|null
*/
public function getExpires() : ?\DateTime{
return $this->expirationDate;
}
/**
* @param \DateTime|null $date
* @throws \InvalidArgumentException
*/
public function setExpires(?\DateTime $date) : void{
if($date !== null){
self::validateDate($date);
}
$this->expirationDate = $date;
}
public function hasExpired() : bool{
/** @noinspection PhpUnhandledExceptionInspection */
$now = new \DateTime();
return $this->expirationDate === null ? false : $this->expirationDate < $now;
}
public function getReason() : string{
return $this->reason;
}
public function setReason(string $reason) : void{
$this->reason = $reason;
}
public function getString() : string{
$str = "";
$str .= $this->getName();
$str .= "|";
$str .= $this->getCreated()->format(self::$format);
$str .= "|";
$str .= $this->getSource();
$str .= "|";
$str .= $this->getExpires() === null ? "Forever" : $this->getExpires()->format(self::$format);
$str .= "|";
$str .= $this->getReason();
return $str;
}
/**
* Hacky function to validate \DateTime objects due to a bug in PHP. format() with "Y" can emit years with more than
* 4 digits, but createFromFormat() with "Y" doesn't accept them if they have more than 4 digits on the year.
*
* @link https://bugs.php.net/bug.php?id=75992
*
* @param \DateTime $dateTime
*
* @throws \InvalidArgumentException if the argument can't be parsed from a formatted date string
*/
private static function validateDate(\DateTime $dateTime) : void{
try{
self::parseDate($dateTime->format(self::$format));
}catch(\RuntimeException $e){
throw new \InvalidArgumentException($e->getMessage(), 0, $e);
}
}
/**
* @param string $date
*
* @return \DateTime|null
* @throws \RuntimeException
*/
private static function parseDate(string $date) : ?\DateTime{
$datetime = \DateTime::createFromFormat(self::$format, $date);
if(!($datetime instanceof \DateTime)){
throw new \RuntimeException("Corrupted date/time: " . implode(", ", \DateTime::getLastErrors()["errors"]));
}
return $datetime;
}
/**
* @param string $str
*
* @return BanEntry|null
* @throws \RuntimeException
*/
public static function fromString(string $str) : ?BanEntry{
if(strlen($str) < 2){
return null;
}
$parts = explode("|", trim($str));
$entry = new BanEntry(trim(array_shift($parts)));
if(!empty($parts)){
$entry->setCreated(self::parseDate(array_shift($parts)));
}
if(!empty($parts)){
$entry->setSource(trim(array_shift($parts)));
}
if(!empty($parts)){
$expire = trim(array_shift($parts));
if($expire !== "" and strtolower($expire) !== "forever"){
$entry->setExpires(self::parseDate($expire));
}
}
if(!empty($parts)){
$entry->setReason(trim(array_shift($parts)));
}
return $entry;
}
}

192
src/permission/BanList.php Normal file
View File

@@ -0,0 +1,192 @@
<?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\permission;
use function fclose;
use function fgets;
use function fopen;
use function fwrite;
use function is_resource;
use function strtolower;
use function trim;
class BanList{
/** @var BanEntry[] */
private $list = [];
/** @var string */
private $file;
/** @var bool */
private $enabled = true;
/**
* @param string $file
*/
public function __construct(string $file){
$this->file = $file;
}
/**
* @return bool
*/
public function isEnabled() : bool{
return $this->enabled;
}
/**
* @param bool $flag
*/
public function setEnabled(bool $flag) : void{
$this->enabled = $flag;
}
/**
* @param string $name
*
* @return BanEntry|null
*/
public function getEntry(string $name) : ?BanEntry{
$this->removeExpired();
return $this->list[strtolower($name)] ?? null;
}
/**
* @return BanEntry[]
*/
public function getEntries() : array{
$this->removeExpired();
return $this->list;
}
/**
* @param string $name
*
* @return bool
*/
public function isBanned(string $name) : bool{
$name = strtolower($name);
if(!$this->isEnabled()){
return false;
}else{
$this->removeExpired();
return isset($this->list[$name]);
}
}
/**
* @param BanEntry $entry
*/
public function add(BanEntry $entry) : void{
$this->list[$entry->getName()] = $entry;
$this->save();
}
/**
* @param string $target
* @param string $reason
* @param \DateTime $expires
* @param string $source
*
* @return BanEntry
*/
public function addBan(string $target, ?string $reason = null, ?\DateTime $expires = null, ?string $source = null) : BanEntry{
$entry = new BanEntry($target);
$entry->setSource($source ?? $entry->getSource());
$entry->setExpires($expires);
$entry->setReason($reason ?? $entry->getReason());
$this->list[$entry->getName()] = $entry;
$this->save();
return $entry;
}
/**
* @param string $name
*/
public function remove(string $name) : void{
$name = strtolower($name);
if(isset($this->list[$name])){
unset($this->list[$name]);
$this->save();
}
}
public function removeExpired() : void{
foreach($this->list as $name => $entry){
if($entry->hasExpired()){
unset($this->list[$name]);
}
}
}
public function load() : void{
$this->list = [];
$fp = @fopen($this->file, "r");
if(is_resource($fp)){
while(($line = fgets($fp)) !== false){
if($line[0] !== "#"){
try{
$entry = BanEntry::fromString($line);
if($entry !== null){
$this->list[$entry->getName()] = $entry;
}
}catch(\RuntimeException $e){
$logger = \GlobalLogger::get();
$logger->critical("Failed to parse ban entry from string \"" . trim($line) . "\": " . $e->getMessage());
}
}
}
fclose($fp);
}else{
\GlobalLogger::get()->error("Could not load ban list");
}
}
/**
* @param bool $writeHeader
*/
public function save(bool $writeHeader = true) : void{
$this->removeExpired();
$fp = @fopen($this->file, "w");
if(is_resource($fp)){
if($writeHeader){
fwrite($fp, "# victim name | ban date | banned by | banned until | reason\n\n");
}
foreach($this->list as $entry){
fwrite($fp, $entry->getString() . "\n");
}
fclose($fp);
}else{
\GlobalLogger::get()->error("Could not save ban list");
}
}
}

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\permission;
abstract class DefaultPermissions{
public const ROOT = "pocketmine";
/**
* @param Permission $perm
* @param Permission $parent
*
* @return Permission
*/
public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{
if($parent instanceof Permission){
$parent->getChildren()[$perm->getName()] = true;
return self::registerPermission($perm);
}
PermissionManager::getInstance()->addPermission($perm);
return PermissionManager::getInstance()->getPermission($perm->getName());
}
public static function registerCorePermissions(){
$parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities"));
$broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent);
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts);
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts);
$broadcasts->recalculatePermissibles();
$commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent);
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), $whitelist);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), $whitelist);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), $whitelist);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), $whitelist);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), $whitelist);
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), $whitelist);
$whitelist->recalculatePermissibles();
$ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), $ban);
self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), $ban);
self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), $ban);
$ban->recalculatePermissibles();
$unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), $unban);
self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), $unban);
$unban->recalculatePermissibles();
$op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), $op);
self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), $op);
$op->recalculatePermissibles();
$save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), $save);
self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), $save);
self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), $save);
$save->recalculatePermissibles();
$time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time);
self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), $time);
$time->recalculatePermissibles();
$kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $kill);
self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), $kill);
$kill->recalculatePermissibles();
self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action", Permission::DEFAULT_TRUE), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents", Permission::DEFAULT_FALSE), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player", Permission::DEFAULT_OP), $commands);
self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty", Permission::DEFAULT_OP), $commands);
$commands->recalculatePermissibles();
$parent->recalculatePermissibles();
}
}

View File

@@ -0,0 +1,75 @@
<?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\permission;
use pocketmine\plugin\Plugin;
interface Permissible extends ServerOperator{
/**
* Checks if this instance has a permission overridden
*
* @param string|Permission $name
*
* @return bool
*/
public function isPermissionSet($name) : bool;
/**
* Returns the permission value if overridden, or the default value if not
*
* @param string|Permission $name
*
* @return bool
*/
public function hasPermission($name) : bool;
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment;
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function removeAttachment(PermissionAttachment $attachment) : void;
/**
* @return void
*/
public function recalculatePermissions() : void;
/**
* @return PermissionAttachmentInfo[]
*/
public function getEffectivePermissions() : array;
}

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\permission;
use pocketmine\plugin\Plugin;
use pocketmine\plugin\PluginException;
use pocketmine\timings\Timings;
use function spl_object_id;
class PermissibleBase implements Permissible{
/** @var ServerOperator */
private $opable;
/** @var Permissible */
private $parent = null;
/**
* @var PermissionAttachment[]
*/
private $attachments = [];
/**
* @var PermissionAttachmentInfo[]
*/
private $permissions = [];
/**
* @param ServerOperator $opable
*/
public function __construct(ServerOperator $opable){
$this->opable = $opable;
if($opable instanceof Permissible){
$this->parent = $opable;
}
}
/**
* @return bool
*/
public function isOp() : bool{
return $this->opable->isOp();
}
/**
* @param bool $value
*/
public function setOp(bool $value) : void{
$this->opable->setOp($value);
}
/**
* @param Permission|string $name
*
* @return bool
*/
public function isPermissionSet($name) : bool{
return isset($this->permissions[$name instanceof Permission ? $name->getName() : $name]);
}
/**
* @param Permission|string $name
*
* @return bool
*/
public function hasPermission($name) : bool{
if($name instanceof Permission){
$name = $name->getName();
}
if($this->isPermissionSet($name)){
return $this->permissions[$name]->getValue();
}
if(($perm = PermissionManager::getInstance()->getPermission($name)) !== null){
$perm = $perm->getDefault();
return $perm === Permission::DEFAULT_TRUE or ($this->isOp() and $perm === Permission::DEFAULT_OP) or (!$this->isOp() and $perm === Permission::DEFAULT_NOT_OP);
}else{
return Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_TRUE or ($this->isOp() and Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_OP) or (!$this->isOp() and Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_NOT_OP);
}
}
/**
* //TODO: tick scheduled attachments
*
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{
if(!$plugin->isEnabled()){
throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled");
}
$result = new PermissionAttachment($plugin, $this->parent ?? $this);
$this->attachments[spl_object_id($result)] = $result;
if($name !== null and $value !== null){
$result->setPermission($name, $value);
}
$this->recalculatePermissions();
return $result;
}
/**
* @param PermissionAttachment $attachment
*/
public function removeAttachment(PermissionAttachment $attachment) : void{
if(isset($this->attachments[spl_object_id($attachment)])){
unset($this->attachments[spl_object_id($attachment)]);
if(($ex = $attachment->getRemovalCallback()) !== null){
$ex->attachmentRemoved($attachment);
}
$this->recalculatePermissions();
}
}
public function recalculatePermissions() : void{
Timings::$permissibleCalculationTimer->startTiming();
$this->clearPermissions();
$permManager = PermissionManager::getInstance();
$defaults = $permManager->getDefaultPermissions($this->isOp());
$permManager->subscribeToDefaultPerms($this->isOp(), $this->parent ?? $this);
foreach($defaults as $perm){
$name = $perm->getName();
$this->permissions[$name] = new PermissionAttachmentInfo($this->parent ?? $this, $name, null, true);
$permManager->subscribeToPermission($name, $this->parent ?? $this);
$this->calculateChildPermissions($perm->getChildren(), false, null);
}
foreach($this->attachments as $attachment){
$this->calculateChildPermissions($attachment->getPermissions(), false, $attachment);
}
Timings::$permissibleCalculationTimer->stopTiming();
}
public function clearPermissions() : void{
$permManager = PermissionManager::getInstance();
$permManager->unsubscribeFromAllPermissions($this->parent ?? $this);
$permManager->unsubscribeFromDefaultPerms(false, $this->parent ?? $this);
$permManager->unsubscribeFromDefaultPerms(true, $this->parent ?? $this);
$this->permissions = [];
}
/**
* @param bool[] $children
* @param bool $invert
* @param PermissionAttachment|null $attachment
*/
private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment) : void{
$permManager = PermissionManager::getInstance();
foreach($children as $name => $v){
$perm = $permManager->getPermission($name);
$value = ($v xor $invert);
$this->permissions[$name] = new PermissionAttachmentInfo($this->parent ?? $this, $name, $attachment, $value);
$permManager->subscribeToPermission($name, $this->parent ?? $this);
if($perm instanceof Permission){
$this->calculateChildPermissions($perm->getChildren(), !$value, $attachment);
}
}
}
/**
* @return PermissionAttachmentInfo[]
*/
public function getEffectivePermissions() : array{
return $this->permissions;
}
}

View File

@@ -0,0 +1,81 @@
<?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\permission;
use pocketmine\plugin\Plugin;
trait PermissibleDelegateTrait{
/** @var PermissibleBase */
private $perm = null;
/**
* @param Permission|string $name
*
* @return bool
*/
public function isPermissionSet($name) : bool{
return $this->perm->isPermissionSet($name);
}
/**
* @param Permission|string $name
*
* @return bool
*/
public function hasPermission($name) : bool{
return $this->perm->hasPermission($name);
}
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{
return $this->perm->addAttachment($plugin, $name, $value);
}
/**
* @param PermissionAttachment $attachment
*/
public function removeAttachment(PermissionAttachment $attachment) : void{
$this->perm->removeAttachment($attachment);
}
public function recalculatePermissions() : void{
$this->perm->recalculatePermissions();
}
/**
* @return PermissionAttachmentInfo[]
*/
public function getEffectivePermissions() : array{
return $this->perm->getEffectivePermissions();
}
}

View File

@@ -0,0 +1,158 @@
<?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);
/**
* Permission related classes
*/
namespace pocketmine\permission;
/**
* Represents a permission
*/
class Permission{
public const DEFAULT_OP = "op";
public const DEFAULT_NOT_OP = "notop";
public const DEFAULT_TRUE = "true";
public const DEFAULT_FALSE = "false";
public static $DEFAULT_PERMISSION = self::DEFAULT_OP;
/** @var string */
private $name;
/** @var string */
private $description;
/**
* @var bool[]
*/
private $children;
/** @var string */
private $defaultValue;
/**
* Creates a new Permission object to be attached to Permissible objects
*
* @param string $name
* @param string $description
* @param string $defaultValue
* @param bool[] $children
*/
public function __construct(string $name, ?string $description = null, ?string $defaultValue = null, array $children = []){
$this->name = $name;
$this->description = $description ?? "";
$this->defaultValue = $defaultValue ?? self::$DEFAULT_PERMISSION;
$this->children = $children;
$this->recalculatePermissibles();
}
/**
* @return string
*/
public function getName() : string{
return $this->name;
}
/**
* @return bool[]
*/
public function &getChildren() : array{
return $this->children;
}
/**
* @return string
*/
public function getDefault() : string{
return $this->defaultValue;
}
/**
* @param string $value
*/
public function setDefault(string $value) : void{
if($value !== $this->defaultValue){
$this->defaultValue = $value;
$this->recalculatePermissibles();
}
}
/**
* @return string
*/
public function getDescription() : string{
return $this->description;
}
/**
* @param string $value
*/
public function setDescription(string $value) : void{
$this->description = $value;
}
/**
* @return Permissible[]
*/
public function getPermissibles() : array{
return PermissionManager::getInstance()->getPermissionSubscriptions($this->name);
}
public function recalculatePermissibles() : void{
$perms = $this->getPermissibles();
PermissionManager::getInstance()->recalculatePermissionDefaults($this);
foreach($perms as $p){
$p->recalculatePermissions();
}
}
/**
* @param string|Permission $name
* @param bool $value
*
* @return Permission|null Permission if $name is a string, null if it's a Permission
*/
public function addParent($name, bool $value) : ?Permission{
if($name instanceof Permission){
$name->getChildren()[$this->getName()] = $value;
$name->recalculatePermissibles();
return null;
}else{
$perm = PermissionManager::getInstance()->getPermission($name);
if($perm === null){
$perm = new Permission($name);
PermissionManager::getInstance()->addPermission($perm);
}
$this->addParent($perm, $value);
return $perm;
}
}
}

View File

@@ -0,0 +1,152 @@
<?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\permission;
use pocketmine\plugin\Plugin;
use pocketmine\plugin\PluginException;
class PermissionAttachment{
/** @var PermissionRemovedExecutor */
private $removed = null;
/**
* @var bool[]
*/
private $permissions = [];
/** @var Permissible */
private $permissible;
/** @var Plugin */
private $plugin;
/**
* @param Plugin $plugin
* @param Permissible $permissible
*
* @throws PluginException
*/
public function __construct(Plugin $plugin, Permissible $permissible){
if(!$plugin->isEnabled()){
throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled");
}
$this->permissible = $permissible;
$this->plugin = $plugin;
}
/**
* @return Plugin
*/
public function getPlugin() : Plugin{
return $this->plugin;
}
/**
* @param PermissionRemovedExecutor $ex
*/
public function setRemovalCallback(PermissionRemovedExecutor $ex) : void{
$this->removed = $ex;
}
/**
* @return PermissionRemovedExecutor|null
*/
public function getRemovalCallback() : ?PermissionRemovedExecutor{
return $this->removed;
}
/**
* @return Permissible
*/
public function getPermissible() : Permissible{
return $this->permissible;
}
/**
* @return bool[]
*/
public function getPermissions() : array{
return $this->permissions;
}
public function clearPermissions() : void{
$this->permissions = [];
$this->permissible->recalculatePermissions();
}
/**
* @param bool[] $permissions
*/
public function setPermissions(array $permissions) : void{
foreach($permissions as $key => $value){
$this->permissions[$key] = (bool) $value;
}
$this->permissible->recalculatePermissions();
}
/**
* @param string[] $permissions
*/
public function unsetPermissions(array $permissions) : void{
foreach($permissions as $node){
unset($this->permissions[$node]);
}
$this->permissible->recalculatePermissions();
}
/**
* @param string|Permission $name
* @param bool $value
*/
public function setPermission($name, bool $value) : void{
$name = $name instanceof Permission ? $name->getName() : $name;
if(isset($this->permissions[$name])){
if($this->permissions[$name] === $value){
return;
}
unset($this->permissions[$name]); //Fixes children getting overwritten
}
$this->permissions[$name] = $value;
$this->permissible->recalculatePermissions();
}
/**
* @param string|Permission $name
*/
public function unsetPermission($name) : void{
$name = $name instanceof Permission ? $name->getName() : $name;
if(isset($this->permissions[$name])){
unset($this->permissions[$name]);
$this->permissible->recalculatePermissions();
}
}
/**
* @return void
*/
public function remove() : void{
$this->permissible->removeAttachment($this);
}
}

View File

@@ -0,0 +1,82 @@
<?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\permission;
class PermissionAttachmentInfo{
/** @var Permissible */
private $permissible;
/** @var string */
private $permission;
/** @var PermissionAttachment|null */
private $attachment;
/** @var bool */
private $value;
/**
* @param Permissible $permissible
* @param string $permission
* @param PermissionAttachment|null $attachment
* @param bool $value
*
* @throws \InvalidStateException
*/
public function __construct(Permissible $permissible, string $permission, ?PermissionAttachment $attachment, bool $value){
$this->permissible = $permissible;
$this->permission = $permission;
$this->attachment = $attachment;
$this->value = $value;
}
/**
* @return Permissible
*/
public function getPermissible() : Permissible{
return $this->permissible;
}
/**
* @return string
*/
public function getPermission() : string{
return $this->permission;
}
/**
* @return PermissionAttachment|null
*/
public function getAttachment() : ?PermissionAttachment{
return $this->attachment;
}
/**
* @return bool
*/
public function getValue() : bool{
return $this->value;
}
}

View File

@@ -0,0 +1,235 @@
<?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\permission;
use pocketmine\timings\Timings;
use function count;
use function spl_object_id;
class PermissionManager{
/** @var PermissionManager|null */
private static $instance = null;
public static function getInstance() : PermissionManager{
if(self::$instance === null){
self::$instance = new self;
}
return self::$instance;
}
/** @var Permission[] */
protected $permissions = [];
/** @var Permission[] */
protected $defaultPerms = [];
/** @var Permission[] */
protected $defaultPermsOp = [];
/** @var Permissible[][] */
protected $permSubs = [];
/** @var Permissible[] */
protected $defSubs = [];
/** @var Permissible[] */
protected $defSubsOp = [];
/**
* @param string $name
*
* @return null|Permission
*/
public function getPermission(string $name) : ?Permission{
return $this->permissions[$name] ?? null;
}
/**
* @param Permission $permission
*
* @return bool
*/
public function addPermission(Permission $permission) : bool{
if(!isset($this->permissions[$permission->getName()])){
$this->permissions[$permission->getName()] = $permission;
$this->calculatePermissionDefault($permission);
return true;
}
return false;
}
/**
* @param string|Permission $permission
*/
public function removePermission($permission) : void{
if($permission instanceof Permission){
unset($this->permissions[$permission->getName()]);
}else{
unset($this->permissions[$permission]);
}
}
/**
* @param bool $op
*
* @return Permission[]
*/
public function getDefaultPermissions(bool $op) : array{
if($op){
return $this->defaultPermsOp;
}else{
return $this->defaultPerms;
}
}
/**
* @param Permission $permission
*/
public function recalculatePermissionDefaults(Permission $permission) : void{
if(isset($this->permissions[$permission->getName()])){
unset($this->defaultPermsOp[$permission->getName()]);
unset($this->defaultPerms[$permission->getName()]);
$this->calculatePermissionDefault($permission);
}
}
/**
* @param Permission $permission
*/
private function calculatePermissionDefault(Permission $permission) : void{
Timings::$permissionDefaultTimer->startTiming();
if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
$this->defaultPermsOp[$permission->getName()] = $permission;
$this->dirtyPermissibles(true);
}
if($permission->getDefault() === Permission::DEFAULT_NOT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
$this->defaultPerms[$permission->getName()] = $permission;
$this->dirtyPermissibles(false);
}
Timings::$permissionDefaultTimer->startTiming();
}
/**
* @param bool $op
*/
private function dirtyPermissibles(bool $op) : void{
foreach($this->getDefaultPermSubscriptions($op) as $p){
$p->recalculatePermissions();
}
}
/**
* @param string $permission
* @param Permissible $permissible
*/
public function subscribeToPermission(string $permission, Permissible $permissible) : void{
if(!isset($this->permSubs[$permission])){
$this->permSubs[$permission] = [];
}
$this->permSubs[$permission][spl_object_id($permissible)] = $permissible;
}
/**
* @param string $permission
* @param Permissible $permissible
*/
public function unsubscribeFromPermission(string $permission, Permissible $permissible) : void{
if(isset($this->permSubs[$permission])){
unset($this->permSubs[$permission][spl_object_id($permissible)]);
if(count($this->permSubs[$permission]) === 0){
unset($this->permSubs[$permission]);
}
}
}
/**
* @param Permissible $permissible
*/
public function unsubscribeFromAllPermissions(Permissible $permissible) : void{
foreach($this->permSubs as $permission => &$subs){
unset($subs[spl_object_id($permissible)]);
if(empty($subs)){
unset($this->permSubs[$permission]);
}
}
}
/**
* @param string $permission
*
* @return array|Permissible[]
*/
public function getPermissionSubscriptions(string $permission) : array{
return $this->permSubs[$permission] ?? [];
}
/**
* @param bool $op
* @param Permissible $permissible
*/
public function subscribeToDefaultPerms(bool $op, Permissible $permissible) : void{
if($op){
$this->defSubsOp[spl_object_id($permissible)] = $permissible;
}else{
$this->defSubs[spl_object_id($permissible)] = $permissible;
}
}
/**
* @param bool $op
* @param Permissible $permissible
*/
public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible) : void{
if($op){
unset($this->defSubsOp[spl_object_id($permissible)]);
}else{
unset($this->defSubs[spl_object_id($permissible)]);
}
}
/**
* @param bool $op
*
* @return Permissible[]
*/
public function getDefaultPermSubscriptions(bool $op) : array{
if($op){
return $this->defSubsOp;
}
return $this->defSubs;
}
/**
* @return Permission[]
*/
public function getPermissions() : array{
return $this->permissions;
}
public function clearPermissions() : void{
$this->permissions = [];
$this->defaultPerms = [];
$this->defaultPermsOp = [];
}
}

View File

@@ -0,0 +1,162 @@
<?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\permission;
class PermissionParser{
/**
* @param bool|string $value
*
* @return string
*
* @throws \InvalidArgumentException
*/
public static function defaultFromString($value) : string{
if(is_bool($value)){
if($value){
return "true";
}else{
return "false";
}
}
switch(strtolower($value)){
case "op":
case "isop":
case "operator":
case "isoperator":
case "admin":
case "isadmin":
return Permission::DEFAULT_OP;
case "!op":
case "notop":
case "!operator":
case "notoperator":
case "!admin":
case "notadmin":
return Permission::DEFAULT_NOT_OP;
case "true":
return Permission::DEFAULT_TRUE;
case "false":
return Permission::DEFAULT_FALSE;
}
throw new \InvalidArgumentException("Unknown permission default name \"$value\"");
}
/**
* @param array $data
* @param string $default
*
* @return Permission[]
*/
public static function loadPermissions(array $data, string $default = Permission::DEFAULT_OP) : array{
$result = [];
foreach($data as $key => $entry){
$result[] = self::loadPermission($key, $entry, $default, $result);
}
return $result;
}
/**
* @param string $name
* @param array $data
* @param string $default
* @param array $output
*
* @return Permission
*
* @throws \Exception
*/
public static function loadPermission(string $name, array $data, string $default = Permission::DEFAULT_OP, array &$output = []) : Permission{
$desc = null;
$children = [];
if(isset($data["default"])){
$value = PermissionParser::defaultFromString($data["default"]);
if($value !== null){
$default = $value;
}else{
throw new \InvalidStateException("'default' key contained unknown value");
}
}
if(isset($data["children"])){
if(is_array($data["children"])){
foreach($data["children"] as $k => $v){
if(is_array($v)){
if(($perm = self::loadPermission($k, $v, $default, $output)) !== null){
$output[] = $perm;
}
}
$children[$k] = true;
}
}else{
throw new \InvalidStateException("'children' key is of wrong type");
}
}
if(isset($data["description"])){
$desc = $data["description"];
}
return new Permission($name, $desc, $default, $children);
}
/**
* @param Permission[] $permissions
*
* @return array
*/
public static function emitPermissions(array $permissions) : array{
$result = [];
foreach($permissions as $permission){
$result[$permission->getName()] = self::emitPermission($permission);
}
ksort($result);
return $result;
}
private static function emitPermission(Permission $permission) : array{
$result = [
"description" => $permission->getDescription(),
"default" => $permission->getDefault()
];
$children = [];
foreach($permission->getChildren() as $name => $bool){
//TODO: really? wtf??? this system is so overengineered it makes my head hurt...
$child = PermissionManager::getInstance()->getPermission($name);
if($child === null){
throw new \UnexpectedValueException("Permission child should be a registered permission");
}
$children[$name] = self::emitPermission($child);
}
if(!empty($children)){
ksort($children);
$result["children"] = $children;
}
return $result;
}
}

View File

@@ -0,0 +1,35 @@
<?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\permission;
interface PermissionRemovedExecutor{
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function attachmentRemoved(PermissionAttachment $attachment) : void;
}

View File

@@ -0,0 +1,41 @@
<?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\permission;
interface ServerOperator{
/**
* Checks if the current object has operator permissions
*
* @return bool
*/
public function isOp() : bool;
/**
* Sets the operator permission for the current object
*
* @param bool $value
*/
public function setOp(bool $value) : void;
}