It runs :O (Added more Permissions, executors and such things)

This commit is contained in:
Shoghi Cervantes 2014-03-26 04:14:53 +01:00
parent b1b8c89227
commit 7ea9e4c862
76 changed files with 3296 additions and 1061 deletions

View File

@ -69,7 +69,7 @@ function __construct(Level $level, $eid, $class, $type = 0, $data = array()){
$this->level = $level;
$this->fallY = false;
$this->fallStart = false;
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
$this->eid = (int) $eid;
$this->type = (int) $type;
$this->class = (int) $class;

View File

@ -104,10 +104,10 @@ abstract class Achievement{
public static function broadcast(Player $player, $achievementId){
if(isset(Achievement::$list[$achievementId])){
if(ServerAPI::request()->api->getProperty("announce-player-achievements") == true){
Player::broadcastChat($player->getUsername() . " has just earned the achievement " . Achievement::$list[$achievementId]["name"]);
if(Server::getInstance()->api->getProperty("announce-player-achievements") == true){
Player::broadcastMessage($player->getDisplayName() . " has just earned the achievement " . Achievement::$list[$achievementId]["name"]);
}else{
$player->sendChat("You have just earned the achievement " . Achievement::$list[$achievementId]["name"]);
$player->sendMessage("You have just earned the achievement " . Achievement::$list[$achievementId]["name"]);
}
return true;

View File

@ -40,7 +40,7 @@ class BanAPI{
private $bannedIPs;
private $cmdWhitelist = array(); //Command WhiteList
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -97,13 +97,13 @@ class BanAPI{
public function permissionsCheck($data, $event){
switch($event){
case "player.flying": //OPs can fly around the server.
if($this->isOp($data->getUsername())){
if($this->isOp($data->getName())){
return true;
}
break;
case "player.block.break":
case "player.block.place": //Spawn protection detection. Allows OPs to place/break blocks in the spawn area.
if(!$this->isOp($data["player"]->getUsername())){
if(!$this->isOp($data["player"]->getName())){
$t = new Vector2($data["target"]->x, $data["target"]->z);
$s = new Vector2(Level::getDefault()->getSpawn()->x, Level::getDefault()->getSpawn()->z);
if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event . ".spawn", $data) !== true){
@ -118,7 +118,7 @@ class BanAPI{
}
if($data["issuer"] instanceof Player){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->getUsername())){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->getName())){
return;
}
}elseif($data["issuer"] === "console" or $data["issuer"] === "rcon"){
@ -148,7 +148,7 @@ class BanAPI{
break;
}
$this->server->api->console->run(implode(" ", $params), $player);
$output .= "Command ran as " . $player->getUsername() . ".\n";
$output .= "Command ran as " . $player->getName() . ".\n";
break;
case "op":
$user = strtolower($params[0]);
@ -163,10 +163,10 @@ class BanAPI{
$output .= $user . " is now op\n";
break;
}
$this->ops->set(strtolower($player->getUsername()));
$this->ops->set(strtolower($player->getName()));
$this->ops->save();
$output .= $player->getUsername() . " is now op\n";
$player->sendChat("You are now op.");
$output .= $player->getName() . " is now op\n";
$player->sendMessage("You are now op.");
break;
case "deop":
$user = strtolower($params[0]);
@ -177,10 +177,10 @@ class BanAPI{
$output .= $user . " is no longer op\n";
break;
}
$this->ops->remove(strtolower($player->getUsername()));
$this->ops->remove(strtolower($player->getName()));
$this->ops->save();
$output .= $player->getUsername() . " is no longer op\n";
$player->sendChat("You are no longer op.");
$output .= $player->getName() . " is no longer op\n";
$player->sendMessage("You are no longer op.");
break;
case "kick":
if(!isset($params[0])){
@ -197,9 +197,9 @@ class BanAPI{
$this->server->schedule(60, array($player, "close"), "You have been kicked: " . $reason); //Forces a kick
$player->blocked = true;
if($issuer instanceof Player){
Player::broadcastChat($player->getUsername() . " has been kicked by " . $issuer->getUsername() . ": $reason\n");
Player::broadcastMessage($player->getName() . " has been kicked by " . $issuer->getName() . ": $reason\n");
}else{
Player::broadcastChat($player->getUsername() . " has been kicked: $reason\n");
Player::broadcastMessage($player->getName() . " has been kicked: $reason\n");
}
}
}
@ -295,9 +295,9 @@ class BanAPI{
$player->kick("You are banned");
}
if($issuer instanceof Player){
Player::broadcastChat($user . " has been banned by " . $issuer->getUsername() . "\n");
Player::broadcastMessage($user . " has been banned by " . $issuer->getName() . "\n");
}else{
Player::broadcastChat($user . " has been banned\n");
Player::broadcastMessage($user . " has been banned\n");
}
$this->kick($user, "Banned");
$output .= "Player \"$user\" added to ban list\n";

View File

@ -227,7 +227,7 @@ class BlockAPI{
);
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -262,7 +262,7 @@ class BlockAPI{
break;
}
$player->addItem(clone $item);
$output .= "Giving " . $item->getCount() . " of " . $item->getName() . " (" . $item->getID() . ":" . $item->getMetadata() . ") to " . $player->getUsername() . "\n";
$output .= "Giving " . $item->getCount() . " of " . $item->getName() . " (" . $item->getID() . ":" . $item->getMetadata() . ") to " . $player->getName() . "\n";
}else{
$output .= "Unknown player.\n";
}

View File

@ -29,7 +29,7 @@ class ChatAPI{
private $server;
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -59,7 +59,7 @@ class ChatAPI{
break;
}
$sender = ($issuer instanceof Player) ? "Server" : ucfirst($issuer);
Player::broadcastChat("[$sender] " . $s);
Player::broadcastMessage("[$sender] " . $s);
break;
case "me":
if(!($issuer instanceof Player)){
@ -69,9 +69,9 @@ class ChatAPI{
$sender = ucfirst($issuer);
}
}else{
$sender = $issuer->getUsername();
$sender = $issuer->getDisplayName();
}
Player::broadcastChat("* $sender " . implode(" ", $params));
Player::broadcastMessage("* $sender " . implode(" ", $params));
break;
case "tell":
if(!isset($params[0]) or !isset($params[1])){
@ -92,12 +92,12 @@ class ChatAPI{
}
}
$mes = implode(" ", $params);
$output .= "[me -> " . ($target instanceof Player ? $target->getUsername() : $target) . "] " . $mes . "\n";
$output .= "[me -> " . ($target instanceof Player ? $target->getDisplayName() : $target) . "] " . $mes . "\n";
if($target instanceof Player){
$target->sendChat("[" . ($sender instanceof Player ? $sender->getUsername() : $sender) . " -> me] " . $mes);
$target->sendMessage("[" . ($sender instanceof Player ? $sender->getDisplayName() : $sender) . " -> me] " . $mes);
}
if($target === "Console" or $sender === "Console"){
console("[INFO] [" . ($sender instanceof Player ? $sender->getUsername() : $sender) . " -> " . ($target instanceof Player ? $target->getUsername() : $target) . "] " . $mes);
console("[INFO] [" . ($sender instanceof Player ? $sender->getDisplayName() : $sender) . " -> " . ($target instanceof Player ? $target->getDisplayName() : $target) . "] " . $mes);
}
break;
}

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/
*
*
*/
namespace PocketMine;
class CommandReader extends \Thread{
private $stream;
/**
* @var resource
*/
private $fp;
private $readline;
/**
* @var \Threaded
*/
private $buffer;
/**
* @param string $stream
*/
public function __construct($stream = "php://stdin"){
$this->stream = $stream;
$this->start(PTHREADS_INHERIT_ALL & ~PTHREADS_INHERIT_CLASSES);
}
private function readLine(){
if(!$this->readline){
$line = trim(fgets($this->fp));
}else{
$line = trim(readline("> "));
if($line != ""){
readline_add_history($line);
}
}
return $line;
}
/**
* Reads a line from console, if available. Returns null if not available
*
* @return string|null
*/
public function getLine(){
if($this->buffer->count() !== 0){
return $this->buffer->synchronized(function(){
return $this->buffer->shift();
});
}
return null;
}
public function run(){
$this->buffer = new \Threaded;
if(extension_loaded("readline") and $this->stream === "php://stdin"){
$this->readline = true;
}else{
$this->readline = false;
$this->fp = fopen($this->stream, "r");
stream_set_blocking($this->fp, 0); //Won't work on Windows :P
}
$lastLine = microtime(true);
while(true){
if(($line = $this->readLine()) !== ""){
$this->buffer->synchronized(function(\Threaded $buffer, $line){
$buffer[] = $line;
}, $this->buffer, $line);
$lastLine = microtime(true);
}elseif((microtime(true) - $lastLine) <= 0.1){ //Non blocking! Sleep to save CPU
usleep(40000);
}
}
}
}

View File

@ -31,7 +31,7 @@ class ConsoleAPI{
$this->help = array();
$this->cmds = array();
$this->alias = array();
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -185,7 +185,7 @@ class ConsoleAPI{
return $this->run($this->alias[$cmd] . ($params !== "" ? " " . $params : ""), $issuer, $cmd);
}
if($issuer instanceof Player){
console("[DEBUG] " . TextFormat::AQUA . $issuer->getUsername() . TextFormat::RESET . " issued server command: " . ltrim("$alias ") . "/$cmd " . $params, true, true, 2);
console("[DEBUG] " . TextFormat::AQUA . $issuer->getName() . TextFormat::RESET . " issued server command: " . ltrim("$alias ") . "/$cmd " . $params, true, true, 2);
}else{
console("[DEBUG] " . TextFormat::YELLOW . "*" . $issuer . TextFormat::RESET . " issued server command: " . ltrim("$alias ") . "/$cmd " . $params, true, true, 2);
}
@ -202,7 +202,7 @@ class ConsoleAPI{
case "u":
case "player":
case "username":
$p = ($issuer instanceof Player) ? $issuer->getUsername() : $issuer;
$p = ($issuer instanceof Player) ? $issuer->getName() : $issuer;
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
@ -215,18 +215,18 @@ class ConsoleAPI{
case "a":
case "all":
if($issuer instanceof Player){
if($this->server->api->ban->isOp($issuer->getUsername())){
if($this->server->api->ban->isOp($issuer->getName())){
$output = "";
foreach(Player::getAll() as $p){
$output .= $this->run($cmd . " " . substr_replace($params, $p->getUsername(), $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
$output .= $this->run($cmd . " " . substr_replace($params, $p->getName(), $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
}
}else{
$issuer->sendChat("You don't have permissions to use this command.\n");
$issuer->sendMessage("You don't have permissions to use this command.\n");
}
}else{
$output = "";
foreach(Player::getAll() as $p){
$output .= $this->run($cmd . " " . substr_replace($params, $p->getUsername(), $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
$output .= $this->run($cmd . " " . substr_replace($params, $p->getName(), $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
}
}
@ -243,7 +243,7 @@ class ConsoleAPI{
return;
}
$p = $l[mt_rand(0, count($l) - 1)]->getUsername();
$p = $l[mt_rand(0, count($l) - 1)]->getName();
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
@ -268,7 +268,7 @@ class ConsoleAPI{
}
if($output != "" and ($issuer instanceof Player)){
$issuer->sendChat(trim($output));
$issuer->sendMessage(trim($output));
}
return $output;

View File

@ -27,7 +27,7 @@ class LevelAPI{
private $server;
public function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){

View File

@ -37,6 +37,7 @@ use PocketMine\NBT\Tag\Float;
use PocketMine\NBT\Tag\Int;
use PocketMine\NBT\Tag\Short;
use PocketMine\NBT\Tag\String;
use PocketMine\Command\CommandSender;
use PocketMine\Network\Protocol\AdventureSettingsPacket;
use PocketMine\Network\Protocol\AnimatePacket;
use PocketMine\Network\Protocol\ChunkDataPacket;
@ -80,11 +81,25 @@ use PocketMine\Utils\Utils;
* Class Player
* @package PocketMine
*/
class Player extends RealHuman{
class Player extends RealHuman/*TODO: implements CommandSender*/{
const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin";
const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user";
const SURVIVAL = 0;
const CREATIVE = 1;
const ADVENTURE = 2;
const SPECTATOR = 3;
const VIEW = Player::SPECTATOR;
const MAX_QUEUE = 2048;
const SURVIVAL_SLOTS = 36;
const CREATIVE_SLOTS = 112;
public static $list = array(); //????
/**
* @var Player[]
*/
public static $list = array();
public $auth = false;
public $CID;
public $MTU;
@ -110,6 +125,7 @@ class Player extends RealHuman{
protected $port;
protected $username;
protected $iusername;
protected $displayName;
protected $startAction = false;
protected $sleeping = false;
protected $chunksOrder = array();
@ -149,7 +165,7 @@ class Player extends RealHuman{
public function __construct($clientID, $ip, $port, $MTU){
$this->bigCnt = 0;
$this->MTU = $MTU;
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
$this->lastBreak = microtime(true);
$this->clientID = $clientID;
$this->CID = Server::clientID($ip, $port);
@ -160,7 +176,7 @@ class Player extends RealHuman{
$this->timeout = microtime(true) + 20;
$this->gamemode = $this->server->gamemode;
$this->level = Level::getDefault();
$this->viewDistance = (int) $this->server->api->getProperty("view-distance");
$this->viewDistance = $this->server->getViewDistance();
$this->slot = 0;
$this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1);
$this->packetStats = array(0, 0);
@ -196,6 +212,14 @@ class Player extends RealHuman{
return $this->connected === true;
}
public function getDisplayName(){
return $this->displayName;
}
public function setDisplayName($name){
$this->displayName = $name;
}
public function getIP(){
return $this->ip;
}
@ -663,11 +687,11 @@ class Player extends RealHuman{
if(($this->gamemode & 0x01) === ($gm & 0x01)){
$this->gamemode = $gm;
$this->sendChat("Your gamemode has been changed to " . $this->getGamemode() . ".\n");
$this->sendMessage("Your gamemode has been changed to " . $this->getGamemode() . ".\n");
}else{
$this->blocked = true;
$this->gamemode = $gm;
$this->sendChat("Your gamemode has been changed to " . $this->getGamemode() . ", you've to do a forced reconnect.\n");
$this->sendMessage("Your gamemode has been changed to " . $this->getGamemode() . ", you've to do a forced reconnect.\n");
$this->server->schedule(30, array($this, "close"), "gamemode change"); //Forces a kick
}
$this->sendSettings();
@ -969,7 +993,7 @@ class Player extends RealHuman{
if(count($u) > 0){
foreach($u as $p){
if($p !== $this){
$p->close($p->getUsername() . " has left the game", "logged in from another location");
$p->close($p->getDisplayName() . " has left the game", "logged in from another location");
}
}
}
@ -1068,7 +1092,7 @@ class Player extends RealHuman{
//$this->heal($this->data->get("health"), "spawn", true);
$this->spawned = true;
$this->spawnToAll();
$this->sendChat($this->server->motd . "\n");
$this->sendMessage($this->server->motd . "\n");
$this->sendInventory();
$this->sendSettings();
@ -1608,7 +1632,7 @@ class Player extends RealHuman{
}else{
$ev = new Event\Player\PlayerChatEvent($this, $message);
if(EventHandler::callEvent($ev) !== Event\Event::DENY){
Player::groupChat(sprintf($ev->getFormat(), $ev->getPlayer()->getUsername(), $ev->getMessage()), $ev->getRecipients());
Player::groupChat(sprintf($ev->getFormat(), $ev->getPlayer()->getDisplayName(), $ev->getMessage()), $ev->getRecipients());
}
}
}
@ -1865,7 +1889,7 @@ class Player extends RealHuman{
*/
public function kick($reason = ""){
if(EventHandler::callEvent($ev = new Event\Player\PlayerKickEvent($this, $reason, "Kicked player " . $this->username . "." . ($reason !== "" ? " With reason: $reason" : ""))) !== Event\Event::DENY){
$this->sendChat("You have been kicked. " . ($reason !== "" ? " Reason: $reason" : "") . "\n");
$this->sendMessage("You have been kicked. " . ($reason !== "" ? " Reason: $reason" : "") . "\n");
$this->close($ev->getQuitMessage(), $reason);
return true;
@ -1879,7 +1903,7 @@ class Player extends RealHuman{
*
* @param string $message
*/
public function sendChat($message){
public function sendMessage($message){
$mes = explode("\n", $message);
foreach($mes as $m){
if(preg_match_all('#@([@A-Za-z_]{1,})#', $m, $matches, PREG_OFFSET_CAPTURE) > 0){
@ -1934,7 +1958,7 @@ class Player extends RealHuman{
Player::saveOffline($this->username, $this->namedtag);
}
if(isset($ev) and $this->username != "" and $this->spawned !== false and $ev->getQuitMessage() != ""){
Player::broadcastChat($ev->getQuitMessage());
Player::broadcastMessage($ev->getQuitMessage());
}
$this->spawned = false;
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
@ -2007,7 +2031,7 @@ class Player extends RealHuman{
*
* @param string $message
*/
public static function broadcastChat($message){
public static function broadcastMessage($message){
self::groupChat($message, self::getAll());
}
@ -2060,7 +2084,7 @@ class Player extends RealHuman{
* @return Compound
*/
public static function getOffline($name){
$server = ServerAPI::request();
$server = Server::getInstance();
$iname = strtolower($name);
if(!file_exists(\PocketMine\DATA . "players/" . $iname . ".dat")){
$spawn = Level::getDefault()->getSafeSpawn();
@ -2182,7 +2206,7 @@ class Player extends RealHuman{
*/
public static function groupChat($message, array $players){
foreach($players as $p){
$p->sendChat($message);
$p->sendMessage($message);
}
}
@ -2191,7 +2215,7 @@ class Player extends RealHuman{
*
* @return string
*/
public function getUsername(){
public function getName(){
return $this->username;
}

View File

@ -30,7 +30,7 @@ class PlayerAPI{
private $server;
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -116,7 +116,7 @@ class PlayerAPI{
break;
}
}
Player::broadcastChat($data["player"]->getUsername() . $message);
Player::broadcastMessage($data["player"]->getName() . $message);
return true;
}
@ -166,7 +166,7 @@ class PlayerAPI{
if($target instanceof Level){
$output .= "Spawnpoint of world " . $target->getName() . " set correctly!\n";
}elseif($target !== $issuer){
$output .= "Spawnpoint of " . $target->getUsername() . " set correctly!\n";
$output .= "Spawnpoint of " . $target->getName() . " set correctly!\n";
}else{
$output .= "Spawnpoint set correctly!\n";
}
@ -229,13 +229,13 @@ class PlayerAPI{
break;
}
if($player->setGamemode($gms[strtolower($setgm)])){
$output .= "Gamemode of " . $player->getUsername() . " changed to " . $player->getGamemode() . "\n";
$output .= "Gamemode of " . $player->getName() . " changed to " . $player->getGamemode() . "\n";
}
break;
case "tp":
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->getUsername();
$name = $issuer->getName();
$target = implode(" ", $params);
}elseif(isset($params[1]) and isset($params[0])){
$name = array_shift($params);
@ -251,7 +251,7 @@ class PlayerAPI{
}
}else{
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->getUsername();
$name = $issuer->getName();
$x = $params[0];
$y = $params[1];
$z = $params[2];
@ -280,7 +280,7 @@ class PlayerAPI{
}
if($player instanceof Player){
$player->harm(1000, "console", true);
$player->sendChat("Ouch. That looks like it hurt.\n");
$player->sendMessage("Ouch. That looks like it hurt.\n");
}else{
$output .= "Usage: /$cmd [player]\n";
}
@ -291,7 +291,7 @@ class PlayerAPI{
break;
}
foreach(Player::$list as $c){
$output .= $c->getUsername() . ", ";
$output .= $c->getName() . ", ";
}
$output = substr($output, 0, -2) . "\n";
break;
@ -306,7 +306,7 @@ class PlayerAPI{
if($lv instanceof Level){
$origin = Player::get($name);
if($origin instanceof Player){
$name = $origin->getUsername();
$name = $origin->getName();
return $origin->teleport($lv->getSafeSpawn());
}
@ -316,10 +316,10 @@ class PlayerAPI{
}
$player = Player::get($target);
if($player instanceof Player and $player->spawned === true){
$target = $player->getUsername();
$target = $player->getName();
$origin = Player::get($name);
if($origin instanceof Player){
$name = $origin->getUsername();
$name = $origin->getName();
return $origin->teleport($player->entity);
}
@ -331,7 +331,7 @@ class PlayerAPI{
public function tppos(&$name, &$x, &$y, &$z){
$player = Player::get($name);
if($player instanceof Player and $player->spawned === true){
$name = $player->getUsername();
$name = $player->getName();
$x = $x{0} === "~" ? $player->x + floatval(substr($x, 1)) : floatval($x);
$y = $y{0} === "~" ? $player->y + floatval(substr($y, 1)) : floatval($y);
$z = $z{0} === "~" ? $player->z + floatval(substr($z, 1)) : floatval($z);

View File

@ -28,7 +28,7 @@ class PluginAPI extends \stdClass{
private $server;
public function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
$this->server->api->console->register("plugins", "", array($this, "commandHandler"));
$this->server->api->console->register("version", "", array($this, "commandHandler"));
$this->server->api->ban->cmdWhitelist("version");
@ -39,19 +39,12 @@ class PluginAPI extends \stdClass{
switch($cmd){
case "plugins":
$output = "Plugins: ";
foreach(PluginManager::getPlugins() as $plugin){
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$d = $plugin->getDescription();
$output .= $d->getName() . ": " . $d->getVersion() . ", ";
}
$output = $output === "Plugins: " ? "No plugins installed.\n" : substr($output, 0, -2) . "\n";
break;
case "version":
$output = "PocketMine-MP " . \PocketMine\VERSION . "" . \PocketMine\CODENAME . "」 API #" . \PocketMine\API_VERSION . " for Minecraft: PE " . \PocketMine\MINECRAFT_VERSION . " protocol #" . Info::CURRENT_PROTOCOL;
if(\PocketMine\GIT_COMMIT !== str_repeat("00", 20)){
$output .= " (git " . \PocketMine\GIT_COMMIT . ")";
}
$output .= "\n";
break;
}
return $output;

View File

@ -23,10 +23,10 @@ namespace {
/**
* Output text to the console, can contain Minecraft-formatted text.
*
* @param $message
* @param bool $EOL
* @param bool $log
* @param int $level
* @param string $message
* @param bool $EOL
* @param bool $log
* @param int $level
*/
function console($message, $EOL = true, $log = true, $level = 1){
PocketMine\console($message, $EOL, $log, $level);
@ -156,8 +156,10 @@ namespace PocketMine {
ini_set("memory_limit", "128M"); //Default
define("PocketMine\\START_TIME", microtime(true));
$opts = getopt("", array("enable-ansi", "disable-ansi", "data-path:", "no-wizard"));
define("PocketMine\\DATA", isset($opts["data-path"]) ? realpath($opts["data-path"]) . DIRECTORY_SEPARATOR : \PocketMine\PATH);
$opts = getopt("", array("enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard"));
define("PocketMine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \PocketMine\PATH);
define("PocketMine\\PLUGIN_PATH", isset($opts["plugins"]) ? realpath($opts["plugins"]) . DIRECTORY_SEPARATOR : \PocketMine\PATH . "plugins/");
if((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])){
define("PocketMine\\ANSI", true);
@ -373,7 +375,6 @@ namespace PocketMine {
exit(1); //Exit with error
}
$gitsha1 = false;
if(file_exists(\PocketMine\PATH . ".git/refs/heads/master")){ //Found Git information!
define("PocketMine\\GIT_COMMIT", strtolower(trim(file_get_contents(\PocketMine\PATH . ".git/refs/heads/master"))));
}else{ //Unknown :(
@ -387,7 +388,7 @@ namespace PocketMine {
}
if(!defined("PARENT_API_EXISTENT")){
$server = new Server();
$server = new Server(\PocketMine\PATH, \PocketMine\DATA, \PocketMine\PLUGIN_PATH);
$server->start();
kill(getmypid()); //Fix for ConsoleAPI being blocked

File diff suppressed because it is too large Load Diff

View File

@ -225,27 +225,6 @@ class ServerAPI{
}
public function checkTickUpdates(){
//Update entities that need update
if(count(Entity::$needUpdate) > 0){
foreach(Entity::$needUpdate as $id => $entity){
if($entity->onUpdate() === false){
unset(Entity::$needUpdate[$id]);
}
}
}
//Update tiles that need update
if(count(Tile::$needUpdate) > 0){
foreach(Tile::$needUpdate as $id => $tile){
if($tile->onUpdate() === false){
unset(Tile::$needUpdate[$id]);
}
}
}
}
public function async(callable $callable, $params = array(), $remove = false){
$cnt = $this->asyncCnt++;
$this->asyncCalls[$cnt] = new \Async($callable, $params);
@ -263,38 +242,6 @@ class ServerAPI{
return $ob;
}
public function autoSave(){
console("[DEBUG] Saving....", true, true, 2);
Level::saveAll();
}
public function sendUsage(){
console("[DEBUG] Sending usage data...", true, true, 2);
$plist = "";
foreach(PluginManager::getPlugins() as $p){
$d = $p->getDescription();
$plist .= str_replace(array(";", ":"), "", $d->getName()) . ":" . str_replace(array(";", ":"), "", $d->getVersion()) . ";";
}
$this->asyncOperation(ASYNC_CURL_POST, array(
"url" => "http://stats.pocketmine.net/usage.php",
"data" => array(
"serverid" => $this->server->serverID,
"port" => $this->server->port,
"os" => Utils::getOS(),
"memory_total" => $this->getProperty("memory-limit"),
"memory_usage" => memory_get_usage(true),
"php_version" => PHP_VERSION,
"version" => VERSION,
"mc_version" => MINECRAFT_VERSION,
"protocol" => Info::CURRENT_PROTOCOL,
"online" => count(Player::$list),
"max" => $this->server->maxClients,
"plugins" => $plist,
),
), null);
}
public function __destruct(){
foreach($this->apiList as $i => $ob){
if(method_exists($ob, "__destruct")){
@ -304,73 +251,15 @@ class ServerAPI{
}
}
private function loadProperties(){
if(($memory = str_replace("B", "", strtoupper($this->getProperty("memory-limit")))) !== false){
$value = array("M" => 1, "G" => 1024);
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
if($real < 128){
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
}
@ini_set("memory_limit", $memory);
}else{
$this->setProperty("memory-limit", "128M");
}
if($this->server instanceof Server){
$this->server->setType($this->getProperty("server-type"));
$this->server->maxClients = $this->getProperty("max-players");
$this->server->description = $this->getProperty("description");
$this->server->motd = $this->getProperty("motd");
$this->server->gamemode = $this->getProperty("gamemode");
$this->server->difficulty = $this->getProperty("difficulty");
$this->server->whitelist = $this->getProperty("white-list");
}
}
private function writeProperties(){
$this->config->save();
}
private function parseProperties(){
foreach($this->config->getAll() as $n => $v){
switch($n){
case "last-update":
if($v === false){
$v = time();
}else{
$v = (int) $v;
}
break;
case "gamemode":
case "max-players":
case "server-port":
case "debug":
case "difficulty":
$v = (int) $v;
break;
case "server-id":
if($v !== false){
$v = preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)) : $v;
}
break;
}
$this->config->set($n, $v);
}
if($this->getProperty("hardcore") == 1 and $this->getProperty("difficulty") < 3){
$this->setProperty("difficulty", 3);
}
}
public function init(){
if(!(self::$serverRequest instanceof Server)){
self::$serverRequest = $this->server;
}
Block::init();
Item::init();
Crafting::init();
Level::init();
if($this->getProperty("send-usage", true) !== false){

View File

@ -0,0 +1,735 @@
<?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/
*
*
*/
/**
* PocketMine-MP is the Minecraft: PE multiplayer server software
* Homepage: http://www.pocketmine.net/
*/
namespace PocketMine;
use PocketMine\Entity\Entity;
use PocketMine\Network\Handler;
use PocketMine\Network\Packet;
use PocketMine\Network\Protocol\Info;
use PocketMine\Network\RakNet\Info as RakNetInfo;
use PocketMine\Network\RakNet\Packet as RakNetPacket;
use PocketMine\Plugin\PluginManager;
use PocketMine\Utils\Utils;
use PocketMine\Utils\VersionString;
class ServerOld{
/**
* @var Server
*/
private static $instance;
public $tCnt;
public $serverID;
public $interface;
public $database;
public $version;
public $invisible;
public $tickMeasure;
public $preparedSQL;
public $spawn;
public $whitelist;
public $seed;
public $stop;
public $gamemode;
public $difficulty;
public $name;
public $maxClients;
public $eidCnt;
public $custom;
public $description;
public $motd;
public $port;
public $saveEnabled;
private $rcon;
private $query;
private $serverip;
private $evCnt;
private $handCnt;
private $events;
private $eventsID;
private $handlers;
private $serverType;
private $lastTick;
private $doTick;
private $ticks;
private $memoryStats;
private $schedule;
private $asyncThread;
private $async = array();
private $asyncID = 0;
/**
* @return Server
*/
public static function getInstance(){
if(isset(self::$instance)){
return self::$instance;
}
return null;
}
private function load(){
$this->version = new VersionString();
if(defined("PocketMine\\DEBUG") and \PocketMine\DEBUG >= 0 and function_exists("cli_set_process_title")){
@cli_set_process_title("PocketMine-MP " . \PocketMine\VERSION);
}
console("[INFO] Starting Minecraft PE server on " . ($this->serverip === "0.0.0.0" ? "*" : $this->serverip) . ":" . $this->port);
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = $this->serverID === false ? Utils::readLong(substr(Utils::getUniqueID(true, $this->serverip . $this->port), 8)) : $this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)) : $this->seed;
$this->startDatabase();
$this->api = false;
$this->tCnt = 1;
$this->events = array();
$this->eventsID = array();
$this->handlers = array();
$this->invisible = false;
$this->difficulty = 1;
$this->custom = array();
$this->evCnt = 1;
$this->handCnt = 1;
$this->eidCnt = 1;
$this->maxClients = 20;
$this->schedule = array();
$this->scheduleCnt = 1;
$this->description = "";
$this->memoryStats = array();
$this->spawn = false;
$this->saveEnabled = true;
$this->whitelist = false;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new Handler("255.255.255.255", $this->port, $this->serverip);
$this->stop = false;
$this->ticks = 0;
if(!defined("NO_THREADS")){
$this->asyncThread = new \AsyncMultipleQueue();
}
}
function __construct($name, $gamemode = 0, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
$this->port = (int) $port;
$this->doTick = true;
$this->gamemode = (int) $gamemode;
$this->name = $name;
$this->motd = "Welcome to " . $name;
$this->serverID = false;
$this->seed = $seed;
$this->serverip = $serverip;
self::$instance = $this;
$this->load();
}
/**
* @return float
*/
public function getTPS(){
$v = array_values($this->tickMeasure);
$tps = 40 / ($v[39] - $v[0]);
return round($tps, 4);
}
public function titleTick(){
$time = microtime(true);
if(defined("PocketMine\\DEBUG") and \PocketMine\DEBUG >= 0 and \PocketMine\ANSI === true){
echo "\x1b]0;PocketMine-MP " . VERSION . " | Online " . count(Player::$list) . "/" . $this->maxClients . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "MB | U " . round(($this->interface->bandwidth[1] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " D " . round(($this->interface->bandwidth[0] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " kB/s | TPS " . $this->getTPS() . "\x07";
}
$this->interface->bandwidth = array(0, 0, $time);
}
public function loadEvents(){
if(\PocketMine\ANSI === true){
$this->schedule(30, array($this, "titleTick"), array(), true);
}
$this->schedule(20 * 15, array($this, "checkTicks"), array(), true);
$this->schedule(20 * 60, array($this, "checkMemory"), array(), true);
$this->schedule(20 * 45, "PocketMine\\Utils\\Cache::cleanup", array(), true);
$this->schedule(20, array($this, "asyncOperationChecker"), array(), true);
}
public function checkTicks(){
if($this->getTPS() < 12){
console("[WARNING] Can't keep up! Is the server overloaded?");
}
}
public function checkMemory(){
$info = $this->debugInfo();
$data = $info["memory_usage"] . "," . $info["players"] . "," . $info["entities"];
$i = count($this->memoryStats) - 1;
if($i < 0 or $this->memoryStats[$i] !== $data){
$this->memoryStats[] = $data;
}
}
public function startDatabase(){
$this->preparedSQL = new \stdClass();
$this->preparedSQL->entity = new \stdClass();
$this->database = new \SQLite3(":memory:", SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
$this->query("PRAGMA journal_mode = OFF;");
$this->query("PRAGMA encoding = \"UTF-8\";");
$this->query("PRAGMA secure_delete = OFF;");
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
$this->query("CREATE TABLE blockUpdates (level TEXT, x INTEGER, y INTEGER, z INTEGER, type INTEGER, delay NUMERIC);");
$this->query("CREATE TABLE recipes (id INTEGER PRIMARY KEY, type NUMERIC, recipe TEXT);");
$this->query("PRAGMA synchronous = OFF;");
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
$this->preparedSQL->updateAction = $this->database->prepare("UPDATE actions SET last = :time WHERE ID = :id;");
}
public function query($sql, $fetch = false){
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] " . $this->database->lastErrorMsg() . ". Query: " . $sql, true, true, 0);
if($fetch === true and ($result instanceof \SQLite3Result)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
}
public function debugInfo($console = false){
$info = array();
$info["tps"] = $this->getTPS();
$info["memory_usage"] = round((memory_get_usage() / 1024) / 1024, 2) . "MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage() / 1024) / 1024, 2) . "MB";
$info["entities"] = count(Entity::$list);
$info["players"] = count(Player::$list);
$info["events"] = count($this->eventsID);
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
$info["handlers"] = $info["handlers"]["count"];
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
$info["actions"] = $info["actions"]["count"];
$info["garbage"] = gc_collect_cycles();
$this->handle("server.debug", $info);
if($console === true){
console("[DEBUG] TPS: " . $info["tps"] . ", Memory usage: " . $info["memory_usage"] . " (Peak " . $info["memory_peak_usage"] . "), Entities: " . $info["entities"] . ", Events: " . $info["events"] . ", Handlers: " . $info["handlers"] . ", Actions: " . $info["actions"] . ", Garbage: " . $info["garbage"], true, true, 2);
}
return $info;
}
/**
* @param string $reason
*/
public function close($reason = "server stop"){
if($this->stop !== true){
if(is_int($reason)){
$reason = "signal stop";
}
if(($this->api instanceof ServerAPI) === true){
if(($this->api->chat instanceof ChatAPI) === true){
Player::broadcastMessage("Stopping server...");
}
}
$this->stop = true;
$this->trigger("server.close", $reason);
$this->interface->close();
if(!defined("NO_THREADS")){
@$this->asyncThread->stop = true;
}
}
}
public function setType($type = "normal"){
switch(trim(strtolower($type))){
case "normal":
case "demo":
$this->serverType = "MCCPP;Demo;";
break;
case "minecon":
$this->serverType = "MCCPP;MINECON;";
break;
}
}
public function asyncOperation($type, array $data, callable $callable = null){
if(defined("NO_THREADS")){
return false;
}
$d = "";
$type = (int) $type;
switch($type){
case ASYNC_CURL_GET:
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
break;
case ASYNC_CURL_POST:
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
$d .= Utils::writeShort(count($data["data"]));
foreach($data["data"] as $key => $value){
$d .= Utils::writeShort(strlen($key)) . $key . Utils::writeInt(strlen($value)) . $value;
}
break;
case ASYNC_FUNCTION:
$params = serialize($data["arguments"]);
$d .= Utils::writeShort(strlen($data["function"])) . $data["function"] . Utils::writeInt(strlen($params)) . $params;
break;
default:
return false;
}
$ID = $this->asyncID++;
$this->async[$ID] = $callable;
$this->asyncThread->input .= Utils::writeInt($ID) . Utils::writeShort($type) . $d;
return $ID;
}
public function asyncOperationChecker(){
if(defined("NO_THREADS")){
return false;
}
if(isset($this->asyncThread->output{5})){
$offset = 0;
$ID = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$type = Utils::readShort(substr($this->asyncThread->output, $offset, 2));
$offset += 2;
$data = array();
switch($type){
case ASYNC_CURL_GET:
case ASYNC_CURL_POST:
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$data["result"] = substr($this->asyncThread->output, $offset, $len);
$offset += $len;
break;
case ASYNC_FUNCTION:
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$data["result"] = unserialize(substr($this->asyncThread->output, $offset, $len));
$offset += $len;
break;
}
$this->asyncThread->output = substr($this->asyncThread->output, $offset);
if(isset($this->async[$ID]) and $this->async[$ID] !== null and is_callable($this->async[$ID])){
if(is_array($this->async[$ID])){
$method = $this->async[$ID][1];
$result = $this->async[$ID][0]->$method($data, $type, $ID);
}else{
$result = $this->async[$ID]($data, $type, $ID);
}
}
unset($this->async[$ID]);
}
}
/**
* @param string $event
* @param callable $callable
* @param integer $priority
*
* @return boolean
*/
public function addHandler($event, callable $callable, $priority = 5){
if(!is_callable($callable)){
return false;
}
$priority = (int) $priority;
$hnid = $this->handCnt++;
$this->handlers[$hnid] = $callable;
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (" . $hnid . ", '" . str_replace("'", "\\'", $event) . "', " . $priority . ");");
console("[INTERNAL] New handler " . (is_array($callable) ? get_class($callable[0]) . "::" . $callable[1] : $callable) . " to special event " . $event . " (ID " . $hnid . ")", true, true, 3);
return $hnid;
}
public function dhandle($e, $d){
return $this->handle($e, $d);
}
public function handle($event, &$data){
$this->preparedSQL->selectHandlers->reset();
$this->preparedSQL->selectHandlers->clear();
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute();
$result = null;
if($handlers instanceof \SQLite3Result){
$call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
}
$handlers->finalize();
foreach($call as $hnid => $boolean){
if($result !== false and $result !== true){
$handler = $this->handlers[$hnid];
if(is_array($handler)){
$method = $handler[1];
$result = $handler[0]->$method($data, $event);
}else{
$result = $handler($data, $event);
}
}else{
break;
}
}
}
if($result !== false){
$this->trigger($event, $data);
}
return $result;
}
public function eventHandler($data, $event){
switch($event){
}
}
/**
* TODO
* @return string
*/
public function getGamemode(){
switch($this->gamemode){
case 0:
return "survival";
case 1:
return "creative";
case 2:
return "adventure";
case 3:
return "view";
}
}
public function init(){
register_tick_function(array($this, "tick"));
declare(ticks = 5000); //Minimum TPS for main thread locks
$this->loadEvents();
register_shutdown_function(array($this, "dumpError"));
register_shutdown_function(array($this, "close"));
if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "close"));
pcntl_signal(SIGINT, array($this, "close"));
pcntl_signal(SIGHUP, array($this, "close"));
}
console("[INFO] Default game type: " . strtoupper($this->getGamemode()));
$this->trigger("server.start", microtime(true));
console('[INFO] Done (' . round(microtime(true) - \PocketMine\START_TIME, 3) . 's)! For help, type "help" or "?"');
$this->process();
}
public function dumpError(){
if($this->stop === true){
return;
}
ini_set("memory_limit", "-1"); //Fix error dump not dumped on memory problems
console("[SEVERE] An unrecovereable has ocurred and the server has crashed. Creating an error dump");
$dump = "```\r\n# PocketMine-MP Error Dump " . date("D M j H:i:s T Y") . "\r\n";
$er = error_get_last();
$errorConversion = array(
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",
E_PARSE => "E_PARSE",
E_NOTICE => "E_NOTICE",
E_CORE_ERROR => "E_CORE_ERROR",
E_CORE_WARNING => "E_CORE_WARNING",
E_COMPILE_ERROR => "E_COMPILE_ERROR",
E_COMPILE_WARNING => "E_COMPILE_WARNING",
E_USER_ERROR => "E_USER_ERROR",
E_USER_WARNING => "E_USER_WARNING",
E_USER_NOTICE => "E_USER_NOTICE",
E_STRICT => "E_STRICT",
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
E_DEPRECATED => "E_DEPRECATED",
E_USER_DEPRECATED => "E_USER_DEPRECATED",
);
$er["type"] = isset($errorConversion[$er["type"]]) ? $errorConversion[$er["type"]] : $er["type"];
$dump .= "Error: " . var_export($er, true) . "\r\n\r\n";
if(stripos($er["file"], "plugin") !== false){
$dump .= "THIS ERROR WAS CAUSED BY A PLUGIN. REPORT IT TO THE PLUGIN DEVELOPER.\r\n";
}
$dump .= "Code: \r\n";
$file = @file($er["file"], FILE_IGNORE_NEW_LINES);
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
$dump .= "[" . ($l + 1) . "] " . @$file[$l] . "\r\n";
}
$dump .= "\r\n\r\n";
$dump .= "Backtrace: \r\n";
foreach(getTrace() as $line){
$dump .= "$line\r\n";
}
$dump .= "\r\n\r\n";
$version = new VersionString();
$dump .= "PocketMine-MP version: " . $version . " #" . $version->getNumber() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]\r\n";
$dump .= "Git commit: " . GIT_COMMIT . "\r\n";
$dump .= "uname -a: " . php_uname("a") . "\r\n";
$dump .= "PHP Version: " . phpversion() . "\r\n";
$dump .= "Zend version: " . zend_version() . "\r\n";
$dump .= "OS : " . PHP_OS . ", " . Utils::getOS() . "\r\n";
$dump .= "Debug Info: " . var_export($this->debugInfo(false), true) . "\r\n\r\n\r\n";
global $arguments;
$dump .= "Parameters: " . var_export($arguments, true) . "\r\n\r\n\r\n";
$p = $this->api->getProperties();
if($p["rcon.password"] != ""){
$p["rcon.password"] = "******";
}
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
if(class_exists("PocketMine\\Plugin\\PluginManager", false)){
$dump .= "Loaded plugins:\r\n";
foreach(PluginManager::getPlugins() as $p){
$d = $p->getDescription();
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
}
$dump .= "\r\n\r\n";
}
$extensions = array();
foreach(get_loaded_extensions() as $ext){
$extensions[$ext] = phpversion($ext);
}
$dump .= "Loaded Modules: " . var_export($extensions, true) . "\r\n";
$this->checkMemory();
$dump .= "Memory Usage Tracking: \r\n" . chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9))) . "\r\n";
ob_start();
phpinfo();
$dump .= "\r\nphpinfo(): \r\n" . chunk_split(base64_encode(gzdeflate(ob_get_contents(), 9))) . "\r\n";
ob_end_clean();
$dump .= "\r\n```";
$name = "Error_Dump_" . date("D_M_j-H.i.s-T_Y");
log($dump, $name, true, 0, true);
console("[SEVERE] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
}
public function tick(){
$time = microtime(true);
if($this->lastTick <= ($time - 0.05)){
$this->tickMeasure[] = $this->lastTick = $time;
unset($this->tickMeasure[key($this->tickMeasure)]);
++$this->ticks;
return $this->tickerFunction($time);
}
return 0;
}
public static function clientID($ip, $port){
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
//return $ip . ":" . $port;
}
public function packetHandler(Packet $packet){
$data =& $packet;
$CID = Server::clientID($packet->ip, $packet->port);
if(isset(Player::$list[$CID])){
Player::$list[$CID]->handlePacket($packet);
}else{
switch($packet->pid()){
case RakNetInfo::UNCONNECTED_PING:
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
if($this->invisible === true){
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
if(!isset($this->custom["times_" . $CID])){
$this->custom["times_" . $CID] = 0;
}
$ln = 15;
if($this->description == "" or substr($this->description, -1) != " "){
$this->description .= " ";
}
$txt = substr($this->description, $this->custom["times_" . $CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt));
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType . $this->name . " [" . count(Player::$list) . "/" . $this->maxClients . "] " . $txt;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
$this->custom["times_" . $CID] = ($this->custom["times_" . $CID] + 1) % strlen($this->description);
break;
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
if($packet->structure !== RakNetInfo::STRUCTURE){
console("[DEBUG] Incorrect structure #" . $packet->structure . " from " . $packet->ip . ":" . $packet->port, true, true, 2);
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
$pk->serverID = $this->serverID;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}else{
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_1);
$pk->serverID = $this->serverID;
$pk->mtuSize = strlen($packet->buffer);
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}
break;
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
if($this->invisible === true){
break;
}
new Player($packet->clientID, $packet->ip, $packet->port, $packet->mtuSize); //New Session!
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_2);
$pk->serverID = $this->serverID;
$pk->serverPort = $this->port;
$pk->mtuSize = $packet->mtuSize;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
}
}
public function send(Packet $packet){
return $this->interface->writePacket($packet);
}
public function process(){
$lastLoop = 0;
while($this->stop === false){
$packet = $this->interface->readPacket();
if($packet instanceof Packet){
$this->packetHandler($packet);
$lastLoop = 0;
}
if(($ticks = $this->tick()) === 0){
++$lastLoop;
if($lastLoop < 16){
usleep(1);
}elseif($lastLoop < 128){
usleep(1000);
}elseif($lastLoop < 256){
usleep(2000);
}else{
usleep(4000);
}
}
}
}
public function trigger($event, $data = ""){
if(isset($this->events[$event])){
foreach($this->events[$event] as $evid => $ev){
if(!is_callable($ev)){
$this->deleteEvent($evid);
continue;
}
if(is_array($ev)){
$method = $ev[1];
$ev[0]->$method($data, $event);
}else{
$ev($data, $event);
}
}
}
}
public function schedule($ticks, callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
if(!is_callable($callback)){
return false;
}
$chcnt = $this->scheduleCnt++;
$this->schedule[$chcnt] = array($callback, $data, $eventName);
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(" . $chcnt . ", " . ($ticks / 20) . ", " . microtime(true) . ", " . (((bool) $repeat) === true ? 1 : 0) . ");");
return $chcnt;
}
public function tickerFunction($time){
//actions that repeat every x time will go here
$this->preparedSQL->selectActions->reset();
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
$actions = $this->preparedSQL->selectActions->execute();
$actionCount = 0;
if($actions instanceof \SQLite3Result){
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
$cid = $action["ID"];
$this->preparedSQL->updateAction->reset();
$this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT);
$this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER);
$this->preparedSQL->updateAction->execute();
if(!@is_callable($this->schedule[$cid][0])){
$return = false;
}else{
++$actionCount;
$return = call_user_func($this->schedule[$cid][0], $this->schedule[$cid][1], $this->schedule[$cid][2]);
}
if($action["repeat"] == 0 or $return === false){
$this->query("DELETE FROM actions WHERE ID = " . $action["ID"] . ";");
$this->schedule[$cid] = null;
unset($this->schedule[$cid]);
}
}
$actions->finalize();
}
return $actionCount;
}
public function event($event, callable $func){
if(!is_callable($func)){
return false;
}
$evid = $this->evCnt++;
if(!isset($this->events[$event])){
$this->events[$event] = array();
}
$this->events[$event][$evid] = $func;
$this->eventsID[$evid] = $event;
console("[INTERNAL] Attached " . (is_array($func) ? get_class($func[0]) . "::" . $func[1] : $func) . " to event " . $event . " (ID " . $evid . ")", true, true, 3);
return $evid;
}
public function deleteEvent($id){
$id = (int) $id;
if(isset($this->eventsID[$id])){
$ev = $this->eventsID[$id];
$this->eventsID[$id] = null;
unset($this->eventsID[$id]);
$this->events[$ev][$id] = null;
unset($this->events[$ev][$id]);
if(count($this->events[$ev]) === 0){
unset($this->events[$ev]);
}
}
}
}

View File

@ -33,7 +33,7 @@ class TimeAPI{
private $server;
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){

View File

@ -23,7 +23,7 @@ namespace PocketMine\Block;
use PocketMine\Item\Item;
use PocketMine\Network\Protocol\ChatPacket;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
class Bed extends Transparent{
@ -35,7 +35,7 @@ class Bed extends Transparent{
}
public function onActivate(Item $item, PocketMine\Player $player = null){
if($player instanceof PocketMine\Player and ServerAPI::request()->api->time->getPhase($this->level) !== "night"){
if($player instanceof PocketMine\Player and Server::getInstance()->api->time->getPhase($this->level) !== "night"){
$pk = new ChatPacket;
$pk->message = "You can only sleep at night";
$player->dataPacket($pk);

View File

@ -59,7 +59,7 @@ class Beetroot extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(BEETROOT_SEEDS, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(BEETROOT_SEEDS, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -35,7 +35,7 @@ class BrownMushroom extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -24,7 +24,7 @@ namespace PocketMine\Block;
use PocketMine\Item\Item;
use PocketMine\Level\Level;
use PocketMine\Math\Vector3 as Vector3;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
class Cactus extends Transparent{
@ -39,7 +39,7 @@ class Cactus extends Transparent{
$down = $this->getSide(0);
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){ //Replace with common break method
$this->level->setBlock($this, new Air(), false);
ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
Server::getInstance()->api->entity->drop($this, Item::get($this->id));
return Level::BLOCK_UPDATE_NORMAL;
}

View File

@ -67,7 +67,7 @@ class Carpet extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id, $this->meta, 1));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id, $this->meta, 1));
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -59,7 +59,7 @@ class Carrot extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(CARROT, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(CARROT, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -46,7 +46,7 @@ class CyanFlower extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -46,7 +46,7 @@ class Dandelion extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -23,7 +23,7 @@ namespace PocketMine\Block;
use PocketMine\Item\Item;
use PocketMine\Level\Level;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
class Fallable extends Solid{
@ -35,7 +35,7 @@ class Fallable extends Solid{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, PocketMine\Player $player = null){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->blockUpdate(clone $this, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->blockUpdate(clone $this, Level::BLOCK_UPDATE_NORMAL);
return $ret;
}

View File

@ -23,7 +23,7 @@ namespace PocketMine\Block;
use PocketMine\Item\Item;
use PocketMine\Level\Level;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
class Generic extends Block{
@ -59,7 +59,7 @@ class Generic extends Block{
"z" => $this->z + 0.5,
"Tile" => $this->id,
);
$server = ServerAPI::request();
$server = Server::getInstance();
$this->level->setBlock($this, new Air(), false, false, true);
//TODO
//$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);

View File

@ -55,7 +55,7 @@ class Ladder extends Transparent{
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
/*if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, Item::get(LADDER, 0, 1));
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
$this->level->setBlock($this, new Air(), true, true, true);
return Level::BLOCK_UPDATE_NORMAL;
}*/

View File

@ -24,7 +24,7 @@ namespace PocketMine\Block;
use PocketMine\Item\Item;
use PocketMine\Level\Level;
use PocketMine\Level\Position;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
class Lava extends Liquid{
@ -35,7 +35,7 @@ class Lava extends Liquid{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, PocketMine\Player $player = null){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(clone $this, 40, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(clone $this, 40, Level::BLOCK_UPDATE_NORMAL);
return $ret;
}
@ -104,7 +104,7 @@ class Lava extends Liquid{
if($level !== 0x07){
if($down instanceof Air || $down instanceof Lava){
$this->level->setBlock($down, new Lava(0x01), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
@ -112,7 +112,7 @@ class Lava extends Liquid{
}elseif($b->isFlowable === true){
$this->level->setBlock($b, new Lava(min($level + 2, 7)), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
}
}
@ -126,7 +126,7 @@ class Lava extends Liquid{
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($sb, new Air(), false, false, true);
}
@ -137,12 +137,12 @@ class Lava extends Liquid{
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($b, new Air(), false, false, true);
}
}
//ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
//Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($this, new Air(), false, false, true);

View File

@ -125,11 +125,11 @@ class Leaves extends Transparent{
$this->level->setBlock($this, new Air(), false, false, true);
if(mt_rand(1, 20) === 1){ //Saplings
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(Item::SAPLING, $this->meta & 0x03, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(Item::SAPLING, $this->meta & 0x03, 1));
}
if(($this->meta & 0x03) === self::OAK and mt_rand(1, 200) === 1){ //Apples
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(Item::APPLE, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(Item::APPLE, 0, 1));
}
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -47,7 +47,7 @@ class MelonStem extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(MELON_SEEDS, 0, mt_rand(0, 2)));
//Server::getInstance()->api->entity->drop($this, Item::get(MELON_SEEDS, 0, mt_rand(0, 2)));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -61,7 +61,7 @@ class Potato extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(POTATO, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(POTATO, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -47,7 +47,7 @@ class PumpkinStem extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(PUMPKIN_SEEDS, 0, mt_rand(0, 2)));
//Server::getInstance()->api->entity->drop($this, Item::get(PUMPKIN_SEEDS, 0, mt_rand(0, 2)));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -35,7 +35,7 @@ class RedMushroom extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -75,7 +75,7 @@ class Sapling extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -61,7 +61,7 @@ class SignPost extends Transparent{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(SIGN, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(SIGN, 0, 1));
$this->level->setBlock($this, new Air(), true, true, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -66,7 +66,7 @@ class Sugarcane extends Flowable{
$down = $this->getSide(0);
if($down->isTransparent === true and $down->getID() !== self::SUGARCANE_BLOCK){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(SUGARCANE));
//Server::getInstance()->api->entity->drop($this, Item::get(SUGARCANE));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -45,7 +45,7 @@ class TNT extends Solid{
);
$this->level->setBlock($this, new Air(), false, false, true);
//TODO
//$e = ServerAPI::request()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
//$e = Server::getInstance()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
//$e->spawnToAll();
return true;

View File

@ -46,7 +46,7 @@ class Torch extends Flowable{
if($this->getSide($faces[$side])->isTransparent === true and !($side === 0 and $this->getSide(0)->getID() === self::FENCE)){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get($this->id, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get($this->id, 0, 1));
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -25,7 +25,7 @@ use PocketMine\Item\Item;
use PocketMine\Level\Level;
use PocketMine\Level\Position;
use PocketMine;
use PocketMine\ServerAPI;
use PocketMine\Server;
class Water extends Liquid{
public function __construct($meta = 0){
@ -35,7 +35,7 @@ class Water extends Liquid{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, PocketMine\Player $player = null){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(clone $this, 10, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(clone $this, 10, Level::BLOCK_UPDATE_NORMAL);
return $ret;
}
@ -110,7 +110,7 @@ class Water extends Liquid{
if($level !== 0x07){
if($down instanceof Air || $down instanceof Water){
$this->level->setBlock($down, new Water(0x01), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($down, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($down, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
@ -120,7 +120,7 @@ class Water extends Liquid{
}
}elseif($b->isFlowable === true){
$this->level->setBlock($b, new Water($level + 1), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
}
}
@ -134,7 +134,7 @@ class Water extends Liquid{
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($sb, new Air(), false, false, true);
}
@ -145,12 +145,12 @@ class Water extends Liquid{
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($b, new Air(), false, false, true);
}
}
//ServerAPI::request()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
//Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($this, new Air(), false, false, true);
}

View File

@ -61,7 +61,7 @@ class Wheat extends Flowable{
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//ServerAPI::request()->api->entity->drop($this, Item::get(WHEAT_SEEDS, 0, 1));
//Server::getInstance()->api->entity->drop($this, Item::get(WHEAT_SEEDS, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;

View File

@ -0,0 +1,296 @@
<?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/
*
*
*/
/**
* Command handling related classes
*/
namespace PocketMine\Command;
use PocketMine;
use PocketMine\Utils\TextFormat;
abstract class Command{
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $nextLabel;
/**
* @var string
*/
private $label;
/**
* @var string[]
*/
private $aliases = array();
/**
* @var string[]
*/
private $activeAliases = array();
/**
* @var CommandMap
*/
private $commandMap = null;
/**
* @var string
*/
protected $description = "";
/**
* @var string
*/
protected $usageMessage;
/**
* @var string
*/
private $permission = null;
/**
* @var string
*/
private $permissionMessage = null;
/**
* @param string $name
* @param string $description
* @param string $usageMessage
* @param string[] $aliases
*/
protected function __construct($name, $description = "", $usageMessage = null, array $aliases = array()){
$this->name = $name;
$this->nextLabel = $name;
$this->label = $name;
$this->description = $description;
$this->usageMessage = $usageMessage === null ? "/" . $name : $usageMessage;
$this->aliases = $aliases;
$this->activeAliases = (array) $aliases;
}
/**
* @param CommandSender $sender
* @param string $commandLabel
* @param string[] $args
*
* @return mixed
*/
public abstract function execute(CommandSender $sender, $commandLabel, array $args);
/**
* @return string
*/
public function getName(){
return $this->name;
}
/**
* @return string
*/
public function getPermission(){
return $this->permission;
}
/**
* @param string|null $permission
*/
public function setPermission($permission){
$this->permission = $permission;
}
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermission(CommandSender $target){
if($this->testPermissionSilent($target)){
return true;
}
if($this->permissionMessage === null){
$target->sendMessage(TextFormat::RED . "You don't have permissions to use this command.");
}elseif($this->permissionMessage !== ""){
$target->sendMessage(str_replace("<permission>", $this->permission, $this->permissionMessage));
}
return false;
}
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermissionSilent(CommandSender $target){
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(){
return $this->label;
}
public function setLabel($name){
$this->nextLabel = $name;
if(!$this->isRegistered()){
$this->label = $name;
return true;
}
return false;
}
/**
* Registers the command into a Command map
*
* @param CommandMap $commandMap
*
* @return bool
*/
public function register(CommandMap $commandMap){
if($this->allowChangesFrom($commandMap)){
$this->commandMap = $commandMap;
return true;
}
return false;
}
/**
* @param CommandMap $commandMap
*
* @return bool
*/
public function unregister(CommandMap $commandMap){
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){
return $this->commandMap === null or $this->commandMap === $commandMap;
}
/**
* @return bool
*/
public function isRegistered(){
return $this->commandMap !== null;
}
/**
* @return string[]
*/
public function getAliases(){
return $this->activeAliases;
}
/**
* @return string
*/
public function getPermissionMessage(){
return $this->permissionMessage;
}
/**
* @return string
*/
public function getDescription(){
return $this->description;
}
/**
* @return string
*/
public function getUsage(){
return $this->usageMessage;
}
/**
* @param string[] $aliases
*/
public function setAliases(array $aliases){
$this->aliases = $aliases;
if(!$this->isRegistered()){
$this->activeAliases = (array) $aliases;
}
}
/**
* @param string $description
*/
public function setDescription($description){
$this->description = $description;
}
/**
* @param string $permissionMessage
*/
public function setPermissionMessage($permissionMessage){
$this->permissionMessage = $permissionMessage;
}
/**
* @param string $usage
*/
public function setUsage($usage){
$this->usageMessage = $usage;
}
/**
* TODO: static::broadcastCommandMessage()
*
* @param CommandSender $source
* @param string $message
* @param bool $sendToSource
*/
public static function broadcastCommandMessage(CommandSender $source, $message, $sendToSource = true){
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
interface CommandExecutor{
/**
* @param CommandSender $sender
* @param Command $command
* @param string $label
* @param string[] $args
*
* @return boolean
*/
public function onCommand(CommandSender $sender, Command $command, $label, array $args);
}

View File

@ -0,0 +1,62 @@
<?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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
interface CommandMap{
/**
* @param string $fallbackPrefix
* @param Command[] $commands
*/
public function registerAll($fallbackPrefix, array $commands);
/**
* @param string $fallbackPrefix
* @param Command $command
* @param string $label
*/
public function register($fallbackPrefix, Command $command, $label = null);
/**
* @param CommandSender $sender
* @param string $cmdLine
*
* @return boolean
*/
public function dispatch(CommandSender $sender, $cmdLine);
/**
* @return void
*/
public function clearCommands();
/**
* @param string $name
*
* @return Command
*/
public function getCommand($name);
}

View File

@ -0,0 +1,45 @@
<?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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
use PocketMine\Permission\Permissible;
interface CommandSender extends Permissible{
/**
* @param string $message
*/
public function sendMessage($message);
/**
* @return PocketMine\Server
*/
public function getServer();
/**
* @return string
*/
public function getName();
}

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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
use PocketMine\Permission\PermissibleBase;
use PocketMine\Permission\PermissionAttachment;
use PocketMine\Plugin\Plugin;
class ConsoleCommandSender implements CommandSender{
private $perm;
public function __construct(){
$this->perm = new PermissibleBase($this);
}
/**
* @param PocketMine\Permission\Permission|string $name
*
* @return bool
*/
public function isPermissionSet($name){
return $this->perm->isPermissionSet($name);
}
/**
* @param PocketMine\Permission\Permission|string $name
*
* @return bool
*/
public function hasPermission($name){
return $this->perm->hasPermission($name);
}
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PocketMine\Permission\PermissionAttachment
*/
public function addAttachment(Plugin $plugin, $name = null, $value = null){
return $this->perm->addAttachment($plugin, $name, $value);
}
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function removeAttachment(PermissionAttachment $attachment){
$this->perm->removeAttachment($attachment);
}
public function recalculatePermissions(){
$this->perm->recalculatePermissions();
}
/**
* @return PocketMine\Permission\PermissionAttachmentInfo[]
*/
public function getEffectivePermissions(){
return $this->perm->getEffectivePermissions();
}
/**
* @return bool
*/
public function isPlayer(){
return false;
}
/**
* @return PocketMine\Server
*/
public function getServer(){
return PocketMine\Server::getInstance();
}
/**
* @param string $message
*/
public function sendMessage($message){
foreach(explode("\n", $message) as $line){
$line = trim($line);
console($line);
}
}
/**
* @return string
*/
public function getName(){
return "CONSOLE";
}
/**
* @return bool
*/
public function isOp(){
return true;
}
/**
* @param bool $value
*/
public function setOp($value){
}
}

View File

@ -0,0 +1,71 @@
<?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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
use PocketMine\Plugin\Plugin;
class PluginCommand extends Command{
/**
* @var Plugin
*/
private $owningPlugin;
/**
* @var CommandExecutor
*/
private $executor;
protected function __construct($name, Plugin $owner){
parent::__construct($name);
$this->owningPlugin = $owner;
$this->executor = $owner;
$this->usageMessage = "";
}
public function execute(CommandSender $sender, $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 !== ""){
$sender->sendMessage($this->usageMessage);
}
return $success;
}
/**
* @return Plugin
*/
public function getPlugin(){
return $this->owningPlugin;
}
}

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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
interface RemoteConsoleCommandSender extends CommandSender{
}

View File

@ -0,0 +1,153 @@
<?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/
*
*
*/
namespace PocketMine\Command;
use PocketMine;
use PocketMine\Server;
use PocketMine\Command\Defaults\VersionCommand;
use PocketMine\Command\Defaults\VanillaCommand;
class SimpleCommandMap implements CommandMap{
/**
* @var Command[]
*/
protected $knownCommands = array();
/**
* @var Server
*/
private $server;
public function __construct(Server $server){
$this->server = $server;
$this->setDefaultCommands();
}
private function setDefaultCommands(){
//TODO
$this->register("pocketmine", new VersionCommand("version"));
}
public function registerAll($fallbackPrefix, array $commands){
foreach($commands as $command){
$this->register($fallbackPrefix, $command);
}
}
public function register($fallbackPrefix, Command $command, $label = null){
if($label === null){
$label = $command->getName();
}
$label = strtolower(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;
}
private function registerAlias(Command $command, $isAlias, $fallbackPrefix, $label){
$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() === $label){
return false;
}
if(!$isAlias){
$command->setLabel($label);
}
$this->knownCommands[$label] = $command;
return true;
}
public function dispatch(CommandSender $sender, $commandLine){
$args = explode(" ", $commandLine);
if(count($args) === 0){
return false;
}
$sentCommandLabel = strtolower(array_shift($args));
$target = $this->getCommand($sentCommandLabel);
if($target === null){
return false;
}
$target->execute($sender, $sentCommandLabel, $args);
return true;
}
public function clearCommands(){
foreach($this->knownCommands as $command){
$command->unregister($this);
}
$this->knownCommands = array();
$this->setDefaultCommands();
}
public function getCommand($name){
if(isset($this->knownCommands[$name])){
return $this->knownCommands[$name];
}
return null;
}
/**
* @return Command[]
*/
public function getCommands(){
return $this->knownCommands;
}
/**
* @return void
*/
public function registerServerAliases(){
//TODO
}
}

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/
*
*
*/
namespace PocketMine\Command\Defaults;
use PocketMine;
use PocketMine\Command\Command;
use PocketMine\Command\CommandSender;
abstract class VanillaCommand extends Command{
//TODO: increment chunk indexes
const MAX_COORD = 524288;
const MIN_COORD = -524288;
protected function __construct($name, $description = "", $usageMessage = null, array $aliases = array()){
parent::__construct($name, $description, $usageMessage, $aliases);
}
protected function getInteger(CommandSender $sender, $value, $min = self::MIN_COORD, $max = self::MAX_COORD){
$i = (int) $value;
if($i < $min){
$i = $min;
}elseif($i > $max){
$i = $max;
}
return $i;
}
protected function getRelativeDouble($original, CommandSender $sender, $input){
if($input{0} === "~"){
$value = $this->getDouble($sender, substr($input, 1));
return $original + $value;
}
return $this->getDouble($input);
}
protected function getDouble(CommandSender $sender, $value, $min = self::MIN_COORD, $max = self::MAX_COORD){
$i = (double) $value;
if($i < $min){
$i = $min;
}elseif($i > $max){
$i = $max;
}
return $i;
}
}

View File

@ -0,0 +1,97 @@
<?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/
*
*
*/
namespace PocketMine\Command\Defaults;
use PocketMine;
use PocketMine\Command\CommandSender;
use PocketMine\Utils\TextFormat;
class VersionCommand extends VanillaCommand{
public function __construct($name){
parent::__construct(
$name,
"Gets the version of this server including any plugins in use",
"/version [plugin name]",
["ver", "about"]
);
$this->setPermission("pocketmine.command.version");
}
public function execute(CommandSender $sender, $currentAlias, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) === 0){
$output = "This server is running PocketMine-MP version " . PocketMine\Server::getInstance()->getPocketMineVersion() . "" . PocketMine\Server::getInstance()->getCodename() . "」 (Implementing API version " . PocketMine\Server::getInstance()->getApiVersion() . " for Minecraft: PE " . PocketMine\Server::getInstance()->getVersion() . " protocol version " . PocketMine\Network\Protocol\Info::CURRENT_PROTOCOL . ")";
if(\PocketMine\GIT_COMMIT !== str_repeat("00", 20)){
$output .= " [git " . \PocketMine\GIT_COMMIT . "]";
}
$sender->sendMessage($output);
}else{
$pluginName = implode(" ", $args);
$exactPlugin = PocketMine\Server::getInstance()->getPluginManager()->getPlugin($pluginName);
if($exactPlugin instanceof PocketMine\Plugin\Plugin){
$this->describeToSender($exactPlugin, $sender);
return true;
}
$found = false;
$pluginName = strtolower($pluginName);
foreach(PocketMine\Server::getInstance()->getPluginManager()->getPlugins() as $plugin){
if(stripos($plugin->getName(), $pluginName) !== false){
$this->describeToSender($plugin, $sender);
$found = true;
}
}
if(!$found){
$sender->sendMessage("This server is not running any plugin by that name.\nUse /plugins to get a list of plugins.");
}
}
return true;
}
private function describeToSender(PocketMine\Plugin\Plugin $plugin, CommandSender $sender){
$desc = $plugin->getDescription();
$sender->sendMessage(TextFormat::GREEN . $desc->getName() . TextFormat::WHITE . " version " . TextFormat::GREEN . $desc->getVersion());
if($desc->getDescription() != null){
$sender->sendMessage($desc->getDescription());
}
if($desc->getWebsite() != null){
$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

@ -45,9 +45,20 @@ use PocketMine;
abstract class Entity extends Position{
public static $entityCount = 1;
/**
* @var Entity[]
*/
public static $list = array();
/**
* @var Entity[]
*/
public static $needUpdate = array();
/**
* @var Player[]
*/
protected $hasSpawned = array();
protected $id;

View File

@ -25,7 +25,7 @@ use PocketMine\Block\Block;
use PocketMine;
use PocketMine\Level\Level;
use PocketMine\Player;
use PocketMine\ServerAPI;
use PocketMine\Server;
class Painting extends Item{
public function __construct($meta = 0, $count = 1){
@ -35,7 +35,7 @@ class Painting extends Item{
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($target->isTransparent === false and $face > 1 and $block->isSolid === false){
$server = ServerAPI::request();
$server = Server::getInstance();
$faces = array(
2 => 1,
3 => 3,

View File

@ -46,8 +46,8 @@ class SpawnEgg extends Item{
"y" => $block->y,
"z" => $block->z + 0.5,
);
//$e = ServerAPI::request()->api->entity->add($block->level, ENTITY_MOB, $this->meta, $data);
//ServerAPI::request()->api->entity->spawnToAll($e);
//$e = Server::getInstance()->api->entity->add($block->level, ENTITY_MOB, $this->meta, $data);
//Server::getInstance()->api->entity->spawnToAll($e);
if(($player->gamemode & 0x01) === 0){
--$this->count;
}

View File

@ -43,11 +43,12 @@ use PocketMine\Network\Protocol\SetTimePacket;
use PocketMine\Network\Protocol\UpdateBlockPacket;
use PocketMine\Player;
use PocketMine\PMF\LevelFormat;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine\Tile\Chest;
use PocketMine\Tile\Furnace;
use PocketMine\Tile\Sign;
use PocketMine\Tile\Tile;
use PocketMine\Entity\Entity;
use PocketMine\Utils\Cache;
use PocketMine\Utils\Config;
use PocketMine\Utils\Random;
@ -66,15 +67,39 @@ class Level{
const BLOCK_UPDATE_WEAK = 4;
const BLOCK_UPDATE_TOUCH = 5;
protected static $list = array();
/**
* @var Level[]
*/
public static $list = array();
/**
* @var Level
*/
public static $default = null;
/**
* @var Player[]
*/
public $players = array();
/**
* @var Entity[]
*/
public $entities = array();
/**
* @var Entity[][]
*/
public $chunkEntities = array();
/**
* @var Tile[]
*/
public $tiles = array();
/**
* @var Tile[][]
*/
public $chunkTiles = array();
public $nextSave;
@ -84,13 +109,22 @@ class Level{
*/
public $level;
public $stopTime;
private $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount, $generator;
private $time, $startCheck, $startTime;
/**
* @var Server
*/
private $server;
private $name, $usedChunks, $changedBlocks, $changedCount, $generator;
public static function init(){
if(self::$default === null){
$default = ServerAPI::request()->api->getProperty("level-name");
$default = Server::getInstance()->getConfigString("level-name", null);
if($default == ""){
trigger_error("level-name cannot be null", E_USER_ERROR);
return;
}
if(self::loadLevel($default) === false){
self::generateLevel($default, ServerAPI::request()->seed);
self::generateLevel($default, 0); //TODO: Server->getSeed();
self::loadLevel($default);
}
self::$default = self::get($default);
@ -264,7 +298,7 @@ class Level{
}
foreach($blockUpdates->getAll() as $bupdate){
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position((int) $bupdate["x"], (int) $bupdate["y"], (int) $bupdate["z"], $level), (float) $bupdate["delay"], (int) $bupdate["type"]);
Server::getInstance()->api->block->scheduleBlockUpdate(new Position((int) $bupdate["x"], (int) $bupdate["y"], (int) $bupdate["z"], $level), (float) $bupdate["delay"], (int) $bupdate["type"]);
}
return true;
@ -285,14 +319,14 @@ class Level{
return false;
}
$options = array();
if($options === false and ServerAPI::request()->api->getProperty("generator-settings") !== false and trim(ServerAPI::request()->api->getProperty("generator-settings")) != ""){
$options["preset"] = ServerAPI::request()->api->getProperty("generator-settings");
if($options === false and trim(Server::getInstance()->getConfigString("generator-settings", "")) !== ""){
$options["preset"] = Server::getInstance()->getConfigString("generator-settings", "");
}
if($generator !== false and class_exists($generator)){
$generator = new $generator($options);
}else{
if(strtoupper(ServerAPI::request()->api->getProperty("level-type")) == "FLAT"){
if(strtoupper(Server::getInstance()->getLevelType()) == "FLAT"){
$generator = new Flat($options);
}else{
$generator = new Normal($options);
@ -332,15 +366,13 @@ class Level{
}
public function __construct(LevelFormat $level, $name){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
$this->level = $level;
$this->level->level = $this;
$this->startTime = $this->time = (int) $this->level->getData("time");
$this->nextSave = $this->startCheck = microtime(true);
$this->nextSave += 90;
$this->stopTime = false;
$this->server->schedule(1, array($this, "doTick"), array(), true);
$this->server->schedule(20 * 13, array($this, "checkTime"), array(), true);
$this->name = $name;
$this->usedChunks = array();
$this->changedBlocks = array();
@ -372,7 +404,7 @@ class Level{
$this->save();
foreach($this->getPlayers() as $player){
if($this === self::getDefault()){
$player->close($player->getUsername() . " has left the game", "forced level unload");
$player->close($player->getName() . " has left the game", "forced level unload");
}else{
$player->teleport(Level::getDefault()->getSafeSpawn());
}
@ -436,6 +468,10 @@ class Level{
return false;
}
if(($this->server->getTick() % 200) === 0){
$this->checkTime();
}
if($this->level->isGenerating === 0 and count($this->changedCount) > 0){
foreach($this->changedCount as $index => $mini){
for($Y = 0; $Y < 8; ++$Y){
@ -536,9 +572,10 @@ class Level{
if(!isset($this->level)){
return false;
}
if($this->server->saveEnabled === false and $force === false){
//TODO: save enabled/disabled
/*if($this->server->saveEnabled === false and $force === false){
return;
}
}*/
if($extra !== false){
$this->doSaveRoundExtra();
@ -805,7 +842,7 @@ class Level{
new String("Text4", "")
)));
if($player instanceof Player){
$tile->namedtag->creator = new String("creator", $player->getUsername());
$tile->namedtag->creator = new String("creator", $player->getName());
}
}
$item->setCount($item->getCount() - 1);

View File

@ -33,7 +33,7 @@ use PocketMine\Network\Query\QueryHandler;
use PocketMine\Network\Query\QueryPacket;
use PocketMine\Network\RakNet\Info;
use PocketMine\Network\RakNet\Packet;
use PocketMine\ServerAPI;
use PocketMine\Server;
class Handler{
public $bandwidth;
@ -77,7 +77,7 @@ class Handler{
}
return $packet;
}elseif($pid === 0xfe and $buffer{1} === "\xfd" and ServerAPI::request()->api->query instanceof QueryHandler){
}elseif($pid === 0xfe and $buffer{1} === "\xfd" and Server::getInstance()->api->query instanceof QueryHandler){
$packet = new QueryPacket;
$packet->ip = $source;
$packet->port = $port;
@ -85,7 +85,7 @@ class Handler{
if(EventHandler::callEvent(new PacketReceiveEvent($packet)) === Event::DENY){
return false;
}
ServerAPI::request()->api->query->handle($packet);
Server::getInstance()->api->query->handle($packet);
}else{
$packet = new Packet($pid);
$packet->ip = $source;

View File

@ -28,7 +28,7 @@ namespace PocketMine\Network\Query;
use PocketMine;
use PocketMine\Level\Level;
use PocketMine\Player;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine\Utils\Utils;
class QueryHandler{
@ -36,9 +36,9 @@ class QueryHandler{
public function __construct(){
console("[INFO] Starting GS4 status listener");
$this->server = ServerAPI::request();
$addr = ($ip = $this->server->api->getProperty("server-ip")) != "" ? $ip : "0.0.0.0";
$port = $this->server->api->getProperty("server-port");
$this->server = Server::getInstance();
$addr = ($ip = $this->server->getIp()) != "" ? $ip : "0.0.0.0";
$port = $this->server->getPort();
console("[INFO] Setting query port to $port");
/*
The Query protocol is built on top of the existing Minecraft PE UDP network stack.
@ -59,7 +59,7 @@ class QueryHandler{
public function regenerateInfo(){
$str = "";
$plist = "PocketMine-MP " . PocketMine\VERSION;
$pl = PocketMine\Plugin\PluginManager::getPlugins();
$pl = $this->server->getPluginManager()->getPlugins();
if(count($pl) > 0){
$plist .= ":";
foreach($pl as $p){
@ -70,26 +70,25 @@ class QueryHandler{
}
$KVdata = array(
"splitnum" => chr(128),
"hostname" => $this->server->name,
"gametype" => ($this->server->gamemode & 0x01) === 0 ? "SMP" : "CMP",
"hostname" => $this->server->getServerName(),
"gametype" => ($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP",
"game_id" => "MINECRAFTPE",
"version" => PocketMine\MINECRAFT_VERSION,
"server_engine" => "PocketMine-MP " . PocketMine\VERSION,
"version" => $this->server->getVersion(),
"server_engine" => $this->server->getName() . " " . $this->server->getPocketMineVersion(),
"plugins" => $plist,
"map" => Level::getDefault()->getName(),
"numplayers" => count(Player::$list),
"maxplayers" => $this->server->maxClients,
"whitelist" => $this->server->api->getProperty("white-list") === true ? "on" : "off",
"hostport" => $this->server->api->getProperty("server-port"),
//"hostip" => $this->server->api->getProperty("server-ip", "0.0.0.0")
"maxplayers" => $this->server->getMaxPlayers(),
"whitelist" => $this->server->hasWhitelist() === true ? "on" : "off",
"hostport" => $this->server->getPort()
);
foreach($KVdata as $key => $value){
$str .= $key . "\x00" . $value . "\x00";
}
$str .= "\x00\x01player_\x00\x00";
foreach(Player::$list as $player){
if($player->getUsername() != ""){
$str .= $player->getUsername() . "\x00";
if($player->getName() != ""){
$str .= $player->getName() . "\x00";
}
}
$str .= "\x00";
@ -135,7 +134,7 @@ class QueryHandler{
}
$pk->payload = $this->longData;
}else{
$pk->payload = $this->server->name . "\x00" . (($this->server->gamemode & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . Level::getDefault()->getName() . "\x00" . count(Player::$list) . "\x00" . $this->server->maxClients . "\x00" . Utils::writeLShort($this->server->api->getProperty("server-port")) . $this->server->api->getProperty("server-ip", "0.0.0.0") . "\x00";
$pk->payload = $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . Level::getDefault()->getName() . "\x00" . count(Player::$list) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Utils::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00";
}
$pk->encode();
$this->server->send($pk);

View File

@ -26,7 +26,7 @@
namespace PocketMine\Network\RCON;
use PocketMine;
use PocketMine\ServerAPI;
use PocketMine\Server;
class RCON{
@ -55,7 +55,7 @@ class RCON{
}
@socket_getsockname($this->socket, $addr, $port);
console("[INFO] RCON running on $addr:$port");
ServerAPI::request()->schedule(2, array($this, "check"), array(), true);
Server::getInstance()->schedule(2, array($this, "check"), array(), true);
}
public function stop(){
@ -78,7 +78,7 @@ class RCON{
console($this->workers[$n]->response);
$this->workers[$n]->notify();
}else{
$this->workers[$n]->response = ServerAPI::request()->api->console->run($this->workers[$n]->cmd, "rcon");
$this->workers[$n]->response = Server::getInstance()->api->console->run($this->workers[$n]->cmd, "rcon");
$this->workers[$n]->notify();
}
}

View File

@ -22,6 +22,7 @@
namespace PocketMine\Permission;
use PocketMine;
use PocketMine\Plugin\Plugin;
interface Permissible extends ServerOperator{
@ -43,7 +44,21 @@ interface Permissible extends ServerOperator{
*/
public function hasPermission($name);
//TODO: Attachment
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, $name = null, $value = null);
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function removeAttachment(PermissionAttachment $attachment);
/**

View File

@ -0,0 +1,220 @@
<?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/
*
*
*/
namespace PocketMine\Permission;
use PocketMine;
use PocketMine\Server;
use PocketMine\Plugin\Plugin;
class PermissibleBase implements Permissible{
/**
* @var ServerOperator
*/
private $opable = null;
/**
* @var Permissible
*/
private $parent;
/**
* @var PermissionAttachment[]
*/
private $attachments = array();
/**
* @var PermissionAttachmentInfo[]
*/
private $permissions = array();
/**
* @param ServerOperator $opable
*/
public function __construct(ServerOperator $opable){
$this->opable = $opable;
if($opable instanceof Permissible){
$this->parent = $opable;
}else{
$this->parent = $this;
}
}
/**
* @return bool
*/
public function isOp(){
if($this->opable === null){
return false;
}else{
return $this->opable->isOp();
}
}
/**
* @param bool $value
*/
public function setOp($value){
if($this->opable === null){
trigger_error("Cannot change ip value as no ServerOperator is set", E_USER_WARNING);
return;
}else{
$this->opable->setOp($value);
}
}
/**
* @param Permission|string $name
*
* @return bool
*/
public function isPermissionSet($name){
return isset($this->permissions[$name instanceof Permission ? $name->getName() : $name]);
}
/**
* @param Permission|string $name
*
* @return bool
*/
public function hasPermission($name){
if($name instanceof Permission){
$name = $name->getName();
}
if($this->isPermissionSet($name)){
return $this->permissions[$name]->getValue();
}
if(($perm = Server::getInstance()->getPluginManager()->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, $name = null, $value = null){
if($plugin === null){
trigger_error("Plugin cannot be null", E_USER_WARNING);
return null;
}elseif(!$plugin->isEnabled()){
trigger_error("Plugin ".$plugin->getDescription()->getName()." is disabled", E_USER_WARNING);
return null;
}
$result = new PermissionAttachment($plugin, $this->parent);
$this->attachments[spl_object_hash($result)] = $result;
if($name !== null and $value !== null){
$result->setPermission($name, $value);
}
$this->recalculatePermissions();
return $result;
}
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function removeAttachment(PermissionAttachment $attachment){
if($attachment === null){
trigger_error("Attachment cannot be null", E_USER_WARNING);
return;
}
if(isset($this->attachments[spl_object_hash($attachment)])){
unset($this->attachments[spl_object_hash($attachment)]);
if(($ex = $attachment->getRemovalCallback()) !== null){
$ex->attachmentRemoved($attachment);
}
$this->recalculatePermissions();
}
}
public function recalculatePermissions(){
$this->clearPermissions();
$defaults = Server::getInstance()->getPluginManager()->getDefaultPermissions($this->isOp());
Server::getInstance()->getPluginManager()->subscribeToDefaultPerms($this->isOp(), $this->parent);
foreach($defaults as $perm){
$name = $perm->getName();
$this->permissions[$name] = new PermissionAttachmentInfo($this->parent, $name, null, true);
Server::getInstance()->getPluginManager()->subscribeToPermission($name, $this->parent);
$this->calculateChildPermissions($perm->getChildren(), false, null);
}
foreach($this->attachments as $attachment){
$this->calculateChildPermissions($attachment->getPermissions(), false, $attachment);
}
}
public function clearPermissions(){
foreach(array_keys($this->permissions) as $name){
Server::getInstance()->getPluginManager()->unsubscribeFromPermission($name, $this->parent);
}
Server::getInstance()->getPluginManager()->unsubscribeFromDefaultPerms(false, $this->parent);
Server::getInstance()->getPluginManager()->unsubscribeFromDefaultPerms(true, $this->parent);
$this->permissions = array();
}
/**
* @param bool[] $children
* @param bool $invert
* @param PermissionAttachment $attachment
*/
public function calculateChildPermissions(array $children, $invert, PermissionAttachment $attachment){
foreach(array_keys($children) as $name){
$perm = Server::getInstance()->getPluginManager()->getPermission($name);
$value = $invert === true ? !$children[$name] : $children[$name];
$this->permissions[$name] = new PermissionAttachmentInfo($this->parent, $name, $attachment, $value);
Server::getInstance()->getPluginManager()->subscribeToPermission($name, $this->parent);
if($perm instanceof Permission){
$this->calculateChildPermissions($perm->getChildren(), !$value, $attachment);
}
}
}
/**
* @return PermissionAttachmentInfo[]
*/
public function getEffectivePermissions(){
return $this->permissions;
}
}

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/
*
*
*/
namespace PocketMine\Permission;
use PocketMine;
use PocketMine\Plugin\Plugin;
class PermissionAttachment{
/**
* @var PermissionRemovedExecutor
*/
private $removed = null;
/**
* @var bool[]
*/
private $permissions = array();
/**
* @var Permissible
*/
private $permissible;
/**
* @var Plugin
*/
private $plugin;
/**
* @param Plugin $plugin
* @param Permissible $permissible
*/
public function __construct(Plugin $plugin, Permissible $permissible){
if($plugin === null){
trigger_error("Plugin cannot be null", E_USER_WARNING);
return;
}elseif(!$plugin->isEnabled()){
trigger_error("Plugin ".$plugin->getDescription()->getName()." is disabled", E_USER_WARNING);
return;
}
$this->permissible = $permissible;
$this->plugin = $plugin;
}
/**
* @return Plugin
*/
public function getPlugin(){
return $this->plugin;
}
/**
* @param PermissionRemovedExecutor $ex
*/
public function setRemovalCallback(PermissionRemovedExecutor $ex){
$this->removed = $ex;
}
/**
* @return PermissionRemovedExecutor
*/
public function getRemovalCallback(){
return $this->removed;
}
/**
* @return Permissible
*/
public function getPermissible(){
return $this->permissible;
}
/**
* @return bool[]
*/
public function getPermissions(){
return $this->permissions;
}
/**
* @param string|Permission $name
* @param bool $value
*/
public function setPermission($name, $value){
$this->permissions[$name instanceof Permission ? $name->getName() : $name] = $value;
$this->permissible->recalculatePermissions();
}
/**
* @param string|Permission $name
*/
public function unsetPermission($name){
unset($this->permissions[$name instanceof Permission ? $name->getName() : $name]);
}
/**
* @return void
*/
public function remove(){
$this->permissible->removeAttachment($this);
}
}

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/
*
*
*/
namespace PocketMine\Permission;
use PocketMine;
class PermissionAttachmentInfo{
/**
* @var Permissible
*/
private $permissible;
/**
* @var string
*/
private $permission;
/**
* @var PermissionAttachment
*/
private $attachment;
/**
* @var bool
*/
private $value;
/**
* @param Permissible $permissible
* @param string $permission
* @param PermissionAttachment $attachment
* @param bool $value
*/
public function __construct(Permissible $permissible, $permission, PermissionAttachment $attachment, $value){
if($permissible === null){
trigger_error("Permissible may not be null", E_USER_WARNING);
return;
}elseif($permission === null){
trigger_error("Permission may not be null", E_USER_WARNING);
return;
}
$this->permissible = $permissible;
$this->permission = $permission;
$this->attachment = $attachment;
$this->value = $value;
}
/**
* @return Permissible
*/
public function getPermissible(){
return $this->permissible;
}
/**
* @return string
*/
public function getPermission(){
return $this->permission;
}
/**
* @return PermissionAttachment
*/
public function getAttachment(){
return $this->attachment;
}
/**
* @return bool
*/
public function getValue(){
return $this->value;
}
}

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/
*
*
*/
namespace PocketMine\Permission;
use PocketMine;
interface PermissionRemovedExecutor{
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function attachmentRemoved(PermissionAttachment $attachment);
}

View File

@ -28,56 +28,68 @@ use PocketMine;
/**
* Manages all the plugins, Permissions and Permissibles
*/
abstract class PluginManager{
class PluginManager{
/**
* @var PluginManager
*/
private static $instance = null;
/**
* @var Plugin[]
*/
protected static $plugins = array();
protected $plugins = array();
/**
* @var Permission[]
*/
protected static $permissions = array();
protected $permissions = array();
/**
* @var Permission[]
*/
protected static $defaultPerms = array();
protected $defaultPerms = array();
/**
* @var Permission[]
*/
protected static $defaultPermsOp = array();
protected $defaultPermsOp = array();
/**
* @var Permissible[]
*/
protected static $permSubs = array();
protected $permSubs = array();
/**
* @var Permissible[]
*/
protected static $defSubs = array();
protected $defSubs = array();
/**
* @var Permissible[]
*/
protected static $defSubsOp = array();
protected $defSubsOp = array();
/**
* @var PluginLoader[]
*/
protected static $fileAssociations = array();
protected $fileAssociations = array();
/**
* @return PluginManager
*/
public static function getInstance(){
return self::$instance;
}
/**
* @param string $name
*
* @return null|Plugin
*/
public static function getPlugin($name){
if(isset(static::$plugins[$name])){
return static::$plugins[$name];
public function getPlugin($name){
if(isset($this->plugins[$name])){
return $this->plugins[$name];
}
return null;
@ -88,7 +100,7 @@ abstract class PluginManager{
*
* @return boolean
*/
public static function registerInterface($loader){
public function registerInterface($loader){
if(is_object($loader) and !($loader instanceof PluginLoader)){
return false;
}elseif(is_string($loader)){
@ -99,7 +111,7 @@ abstract class PluginManager{
}
}
static::$fileAssociations[spl_object_hash($loader)] = array($loader, $loader->getPluginFilters());
$this->fileAssociations[spl_object_hash($loader)] = array($loader, $loader->getPluginFilters());
return true;
}
@ -107,8 +119,8 @@ abstract class PluginManager{
/**
* @return Plugin[]
*/
public static function getPlugins(){
return static::$plugins;
public function getPlugins(){
return $this->plugins;
}
/**
@ -116,9 +128,9 @@ abstract class PluginManager{
*
* @return Plugin
*/
public static function loadPlugin($path){
foreach(static::$fileAssociations as $loader){
if(preg_match($loader[1], basename($file)) > 0){
public function loadPlugin($path){
foreach($this->fileAssociations as $loader){
if(preg_match($loader[1], basename($path)) > 0){
$description = $loader[0]->getPluginDescription($path);
if($description instanceof PluginDescription){
return $loader[0]->loadPlugin($path);
@ -134,14 +146,14 @@ abstract class PluginManager{
*
* @return Plugin[]
*/
public static function loadPlugins($directory){
public function loadPlugins($directory){
if(is_dir($directory)){
$plugins = array();
$loadedPlugins = array();
$dependencies = array();
$softDependencies = array();
foreach(new \IteratorIterator(new \DirectoryIterator($directory)) as $file){
foreach(static::$fileAssociations as $loader){
foreach($this->fileAssociations as $loader){
if(preg_match($loader[1], basename($file)) > 0){
$description = $loader[0]->getPluginDescription($file);
if($description instanceof PluginDescription){
@ -236,7 +248,7 @@ abstract class PluginManager{
if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){
unset($plugins[$name]);
$missingDependency = false;
if($plugin = static::loadPlugin($file) and $plugin instanceof Plugin){
if($plugin = $this->loadPlugin($file) and $plugin instanceof Plugin){
$loadedPlugins[$name] = $plugin;
}else{
console("[SEVERE] Could not load plugin '" . $name . "'");
@ -250,7 +262,7 @@ abstract class PluginManager{
unset($softDependencies[$name]);
unset($plugins[$name]);
$missingDependency = false;
if($plugin = static::loadPlugin($file) and $plugin instanceof Plugin){
if($plugin = $this->loadPlugin($file) and $plugin instanceof Plugin){
$loadedPlugins[$name] = $plugin;
}else{
console("[SEVERE] Could not load plugin '" . $name . "'");
@ -279,9 +291,9 @@ abstract class PluginManager{
*
* @return null|Permission
*/
public static function getPermission($name){
if(isset(static::$permissions[$name])){
return static::$permissions[$name];
public function getPermission($name){
if(isset($this->permissions[$name])){
return $this->permissions[$name];
}
return null;
@ -292,10 +304,10 @@ abstract class PluginManager{
*
* @return bool
*/
public static function addPermission(Permission $permission){
if(!isset(static::$permissions[$permission->getName()])){
static::$permissions[$permission->getName()] = $permission;
static::calculatePermissionDefault($permission);
public function addPermission(Permission $permission){
if(!isset($this->permissions[$permission->getName()])){
$this->permissions[$permission->getName()] = $permission;
$this->calculatePermissionDefault($permission);
return true;
}
@ -308,9 +320,9 @@ abstract class PluginManager{
*/
public function removePermission($permission){
if($permission instanceof Permission){
unset(static::$permissions[$permission->getName()]);
unset($this->permissions[$permission->getName()]);
}else{
unset(static::$permissions[$permission]);
unset($this->permissions[$permission]);
}
}
@ -319,45 +331,45 @@ abstract class PluginManager{
*
* @return Permission[]
*/
public static function getDefaultPermissions($op){
public function getDefaultPermissions($op){
if($op === true){
return static::$defaultPermsOp;
return $this->defaultPermsOp;
}else{
return static::$defaultPerms;
return $this->defaultPerms;
}
}
/**
* @param Permission $permission
*/
public static function recalculatePermissionDefaults(Permission $permission){
if(isset(static::$permissions[$permission->getName()])){
unset(static::$defaultPermsOp[$permission->getName()]);
unset(static::$defaultPerms[$permission->getName()]);
static::calculatePermissionDefault($permission);
public function recalculatePermissionDefaults(Permission $permission){
if(isset($this->permissions[$permission->getName()])){
unset($this->defaultPermsOp[$permission->getName()]);
unset($this->defaultPerms[$permission->getName()]);
$this->calculatePermissionDefault($permission);
}
}
/**
* @param Permission $permission
*/
private static function calculatePermissionDefault(Permission $permission){
private function calculatePermissionDefault(Permission $permission){
if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
static::$defaultPermsOp[$permission->getName()] = $permission;
static::dirtyPermissibles(true);
$this->defaultPermsOp[$permission->getName()] = $permission;
$this->dirtyPermissibles(true);
}
if($permission->getDefault() === Permission::DEFAULT_NOT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
static::$defaultPerms[$permission->getName()] = $permission;
static::dirtyPermissibles(false);
$this->defaultPerms[$permission->getName()] = $permission;
$this->dirtyPermissibles(false);
}
}
/**
* @param boolean $op
*/
private static function dirtyPermissibles($op){
foreach(static::getDefaultPermSubscriptions($op) as $p){
private function dirtyPermissibles($op){
foreach($this->getDefaultPermSubscriptions($op) as $p){
$p->recalculatePermissions();
}
}
@ -366,21 +378,21 @@ abstract class PluginManager{
* @param string $permission
* @param Permissible $permissible
*/
public static function subscribeToPermission($permission, Permissible $permissible){
if(!isset(static::$permSubs[$permission])){
public function subscribeToPermission($permission, Permissible $permissible){
if(!isset($this->permSubs[$permission])){
//TODO: Use WeakRef
static::$permSubs[$permission] = array();
$this->permSubs[$permission] = array();
}
static::$permSubs[$permission][spl_object_hash($permissible)] = $permissible;
$this->permSubs[$permission][spl_object_hash($permissible)] = $permissible;
}
/**
* @param string $permission
* @param Permissible $permissible
*/
public static function unsubscribeFromPermission($permission, Permissible $permissible){
if(isset(static::$permSubs[$permission])){
unset(static::$permSubs[$permission][spl_object_hash($permissible)]);
public function unsubscribeFromPermission($permission, Permissible $permissible){
if(isset($this->permSubs[$permission])){
unset($this->permSubs[$permission][spl_object_hash($permissible)]);
}
}
@ -389,9 +401,9 @@ abstract class PluginManager{
*
* @return Permissible[]
*/
public static function getPermissionSubscriptions($permission){
if(isset(static::$permSubs[$permission])){
return static::$permSubs[$permission];
public function getPermissionSubscriptions($permission){
if(isset($this->permSubs[$permission])){
return $this->permSubs[$permission];
}
return array();
@ -401,11 +413,11 @@ abstract class PluginManager{
* @param boolean $op
* @param Permissible $permissible
*/
public static function subscribeToDefaultPerms($op, Permissible $permissible){
public function subscribeToDefaultPerms($op, Permissible $permissible){
if($op === true){
static::$defSubsOp[spl_object_hash($permissible)] = $permissible;
$this->defSubsOp[spl_object_hash($permissible)] = $permissible;
}else{
static::$defSubs[spl_object_hash($permissible)] = $permissible;
$this->defSubs[spl_object_hash($permissible)] = $permissible;
}
}
@ -413,11 +425,11 @@ abstract class PluginManager{
* @param boolean $op
* @param Permissible $permissible
*/
public static function unsubscribeFromDefaultPerms($op, Permissible $permissible){
public function unsubscribeFromDefaultPerms($op, Permissible $permissible){
if($op === true){
unset(static::$defSubsOp[spl_object_hash($permissible)]);
unset($this->defSubsOp[spl_object_hash($permissible)]);
}else{
unset(static::$defSubs[spl_object_hash($permissible)]);
unset($this->defSubs[spl_object_hash($permissible)]);
}
}
@ -426,19 +438,19 @@ abstract class PluginManager{
*
* @return Permissible[]
*/
public static function getDefaultPermSubscriptions($op){
public function getDefaultPermSubscriptions($op){
if($op === true){
return static::$defSubsOp;
return $this->defSubsOp;
}else{
return static::$defSubs;
return $this->defSubs;
}
}
/**
* @return Permission[]
*/
public static function getPermissions(){
return static::$permissions;
public function getPermissions(){
return $this->permissions;
}

View File

@ -1,85 +0,0 @@
<?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/
*
*
*/
namespace PocketMine\PMF;
use PocketMine;
use PocketMine\Utils\Utils;
class Plugin extends PMF{
const VERSION = 0x02;
private $pluginData = array();
public function __construct($file){
$this->load($file);
$this->parseInfo();
$this->parsePlugin();
}
public function getPluginInfo(){
return $this->pluginData;
}
protected function parsePlugin(){
if($this->getType() !== 0x01){
return false;
}
$this->seek(5);
$this->pluginData["fversion"] = ord($this->read(1));
if($this->pluginData["fversion"] > self::VERSION){
return false;
}
$this->pluginData["name"] = $this->read(Utils::readShort($this->read(2), false));
$this->pluginData["version"] = $this->read(Utils::readShort($this->read(2), false));
$this->pluginData["author"] = $this->read(Utils::readShort($this->read(2), false));
if($this->pluginData["fversion"] >= 0x01){
$this->pluginData["apiversion"] = $this->read(Utils::readShort($this->read(2), false));
}else{
$this->pluginData["apiversion"] = Utils::readShort($this->read(2), false);
}
$this->pluginData["class"] = $this->read(Utils::readShort($this->read(2), false));
$this->pluginData["identifier"] = $this->read(Utils::readShort($this->read(2), false)); //Will be used to check for updates
if($this->pluginData["fversion"] >= 0x02){
$data = explode(";", gzinflate($this->read(Utils::readInt($this->read(4)))));
$this->pluginData["extra"] = array();
foreach($data as $v){
$v = trim($v);
if($v != ""){
$v = base64_decode($v);
$kl = strpos($v, ":");
$this->pluginData["extra"][substr($v, 0, $kl)] = substr($v, $kl + 1);
}
}
}else{
$this->pluginData["extra"] = gzinflate($this->read(Utils::readShort($this->read(2), false)));
}
$this->pluginData["code"] = "";
while(!feof($this->fp)){
$this->pluginData["code"] .= $this->read(4096);
}
$this->pluginData["code"] = gzinflate($this->pluginData["code"]);
return true;
}
}

View File

@ -26,7 +26,7 @@ namespace PocketMine\Recipes;
use PocketMine;
use PocketMine\Item\Item;
use PocketMine\ServerAPI;
use PocketMine\Server;
abstract class Crafting{
@ -263,7 +263,6 @@ abstract class Crafting{
foreach(self::$small as $recipe){
$recipe = self::parseRecipe($recipe);
self::$recipes[$id] = $recipe;
self::$lookupTable[0][$recipe[2]];
if(!isset(self::$lookupTable[0][$recipe[2]])){
self::$lookupTable[0][$recipe[2]] = array();
}

View File

@ -56,7 +56,7 @@ class ServerTask extends \Threaded{
*/
private $id;
public function __construct(Plugin $plugin, \Threaded $task, $id = -1, $period = -1){
public function __construct(Plugin $plugin = null, \Threaded $task = null, $id = -1, $period = -1){
$this->plugin = $plugin;
$this->task = $task;
$this->id = $id;

View File

@ -0,0 +1,78 @@
<?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/
*
*
*/
namespace PocketMine\Scheduler;
class TickScheduler extends \Thread{
protected $sleepTime;
protected $ticksPerSecond;
protected $tickMeasure;
public $hasTick;
public function __construct($ticksPerSecond = 20){
$this->ticksPerSecond = (int) $ticksPerSecond;
$this->sleepTime = (int) (1000000 / $this->ticksPerSecond);
$this->tickMeasure = $this->sleepTime;
$this->start(PTHREADS_INHERIT_ALL & ~PTHREADS_INHERIT_CLASSES);
}
/**
* Returns true if clear to run tick
*
* @return bool
*/
public function hasTick(){
return $this->synchronized(function(){
$hasTick = $this->hasTick;
$this->hasTick = false;
return $hasTick === true;
});
}
public function doTick(){
$this->notify();
}
/**
* @return float
*/
public function getTPS(){
return $this->synchronized(function(){
return round(($this->sleepTime / $this->tickMeasure) * $this->ticksPerSecond, 2);
});
}
public function run(){
$tickTime = microtime(true);
$this->hasTick = true;
while(true){
$this->synchronized(function(){
$this->hasTick = true;
$this->wait();
$this->hasTick = false;
});
$this->tickMeasure = (int) ((($time = microtime(true)) - $tickTime) * 1000000);
$tickTime = $time;
usleep($this->sleepTime - 100); //Remove a few ms for processing
}
}
}

View File

@ -29,7 +29,7 @@ use PocketMine\Level\Level;
use PocketMine\Level\Position;
use PocketMine\NBT\Tag\Compound;
use PocketMine\PMF\LevelFormat;
use PocketMine\ServerAPI;
use PocketMine\Server;
use PocketMine;
abstract class Tile extends Position{
@ -38,7 +38,15 @@ abstract class Tile extends Position{
const FURNACE = "Furnace";
public static $tileCount = 1;
/**
* @var Tile[]
*/
public static $list = array();
/**
* @var Tile[]
*/
public static $needUpdate = array();
public $chunkIndex;
@ -68,7 +76,7 @@ abstract class Tile extends Position{
public function __construct(Level $level, Compound $nbt){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
$this->level = $level;
$this->namedtag = $nbt;
$this->closed = false;

View File

@ -319,7 +319,7 @@ class Thread extends Threaded
* @link http://www.php.net/manual/en/thread.start.php
* @return bool A boolean indication of success
*/
public static function globally(Callable $block){}
public static function globally(Callable $block, $args = null){}
}
/**

View File

@ -58,7 +58,7 @@ class ServerSuiteTest{
public function hook(){
testCase("event fired", true, true);
$server = \PocketMine\ServerAPI::request();
$server = \PocketMine\Server::getInstance();
testCase("defaultgamemode", $server->getGamemode(), "survival");