mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
It runs :O (Added more Permissions, executors and such things)
This commit is contained in:
parent
b1b8c89227
commit
7ea9e4c862
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
95
src/PocketMine/CommandReader.php
Normal file
95
src/PocketMine/CommandReader.php
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -27,7 +27,7 @@ class LevelAPI{
|
||||
private $server;
|
||||
|
||||
public function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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){
|
||||
|
735
src/PocketMine/ServerOld.php
Normal file
735
src/PocketMine/ServerOld.php
Normal 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ class TimeAPI{
|
||||
private $server;
|
||||
|
||||
function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
296
src/PocketMine/command/Command.php
Normal file
296
src/PocketMine/command/Command.php
Normal 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){
|
||||
|
||||
}
|
||||
}
|
38
src/PocketMine/command/CommandExecutor.php
Normal file
38
src/PocketMine/command/CommandExecutor.php
Normal 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);
|
||||
|
||||
}
|
62
src/PocketMine/command/CommandMap.php
Normal file
62
src/PocketMine/command/CommandMap.php
Normal 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);
|
||||
|
||||
|
||||
}
|
45
src/PocketMine/command/CommandSender.php
Normal file
45
src/PocketMine/command/CommandSender.php
Normal 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();
|
||||
|
||||
|
||||
}
|
131
src/PocketMine/command/ConsoleCommandSender.php
Normal file
131
src/PocketMine/command/ConsoleCommandSender.php
Normal 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){
|
||||
|
||||
}
|
||||
|
||||
}
|
71
src/PocketMine/command/PluginCommand.php
Normal file
71
src/PocketMine/command/PluginCommand.php
Normal 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;
|
||||
}
|
||||
}
|
28
src/PocketMine/command/RemoteConsoleCommandSender.php
Normal file
28
src/PocketMine/command/RemoteConsoleCommandSender.php
Normal 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{
|
||||
|
||||
}
|
153
src/PocketMine/command/SimpleCommandMap.php
Normal file
153
src/PocketMine/command/SimpleCommandMap.php
Normal 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
|
||||
}
|
||||
|
||||
|
||||
}
|
68
src/PocketMine/command/defaults/VanillaCommand.php
Normal file
68
src/PocketMine/command/defaults/VanillaCommand.php
Normal 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;
|
||||
}
|
||||
}
|
97
src/PocketMine/command/defaults/VersionCommand.php
Normal file
97
src/PocketMine/command/defaults/VersionCommand.php
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
220
src/PocketMine/permission/PermissibleBase.php
Normal file
220
src/PocketMine/permission/PermissibleBase.php
Normal 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;
|
||||
}
|
||||
}
|
122
src/PocketMine/permission/PermissionAttachment.php
Normal file
122
src/PocketMine/permission/PermissionAttachment.php
Normal 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);
|
||||
}
|
||||
}
|
95
src/PocketMine/permission/PermissionAttachmentInfo.php
Normal file
95
src/PocketMine/permission/PermissionAttachmentInfo.php
Normal 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;
|
||||
}
|
||||
}
|
34
src/PocketMine/permission/PermissionRemovedExecutor.php
Normal file
34
src/PocketMine/permission/PermissionRemovedExecutor.php
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
78
src/PocketMine/scheduler/TickScheduler.php
Normal file
78
src/PocketMine/scheduler/TickScheduler.php
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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){}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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");
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user