Merge remote-tracking branch 'origin/master' into Faster-Network

This commit is contained in:
Shoghi Cervantes 2014-01-30 10:10:20 +01:00
commit b56a56df2b
35 changed files with 331 additions and 1243 deletions

View File

@ -1,10 +1,11 @@
language: php language: php
php: php:
- 5.4 - 5.5
before_script: before_script:
- pecl install channel://pecl.php.net/pthreads-0.0.44 - pecl install channel://pecl.php.net/pthreads-0.1.0
- echo | pecl install channel://pecl.php.net/yaml-1.1.1
script: script:
- php src/tests/ServerSuiteTest.php --no-wizard - php src/tests/ServerSuiteTest.php --no-wizard

View File

@ -41,8 +41,9 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__ * __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
* __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__ * __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__ * __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
* __[PHP pthreads](https://github.com/krakjoe/pthreads)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything. * __[PHP pthreads](http://pthreads.org/)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
* __[Spyc](https://github.com/mustangostang/spyc/blob/master/Spyc.php)__ by _[Vlad Andersen](https://github.com/mustangostang)_: A simple YAML loader/dumper class for PHP. * __[PHP YAML](https://code.google.com/p/php-yaml/)__ by _Bryan Davis_: The Yaml PHP Extension provides a wrapper to the LibYAML library.
* __[LibYAML](http://pyyaml.org/wiki/LibYAML)__ by _Kirill Simonov_: A YAML 1.1 parser and emitter written in C.
* __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator * __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax * __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library * __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library

View File

@ -145,6 +145,10 @@ class BanAPI{
break; break;
case "op": case "op":
$user = strtolower($params[0]); $user = strtolower($params[0]);
if($user == NULL){
$output .= "Usage: /op <player>\n";
break;
}
$player = $this->server->api->player->get($user); $player = $this->server->api->player->get($user);
if(!($player instanceof Player)){ if(!($player instanceof Player)){
$this->ops->set($user); $this->ops->set($user);
@ -358,9 +362,7 @@ class BanAPI{
return true; return true;
}elseif($this->bannedIPs->exists($ip, true)){ }elseif($this->bannedIPs->exists($ip, true)){
return true; return true;
} }else{
else
{
return false; return false;
} }
} }
@ -376,9 +378,7 @@ class BanAPI{
return true; return true;
}elseif($this->banned->exists($username, true)){ }elseif($this->banned->exists($username, true)){
return true; return true;
} }else{
else
{
return false; return false;
} }
} }

View File

@ -47,6 +47,9 @@ class ConsoleAPI{
if(!defined("NO_THREADS")){ if(!defined("NO_THREADS")){
$this->loop->stop(); $this->loop->stop();
$this->loop->notify(); $this->loop->notify();
//@fclose($this->loop->fp);
usleep(50000);
$this->loop->kill();
//$this->loop->join(); //$this->loop->join();
} }
} }
@ -128,7 +131,7 @@ class ConsoleAPI{
$max = ceil(count($cmds) / 5); $max = ceil(count($cmds) / 5);
$page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1); $page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1);
$output .= "\x1b[31;1m-\x1b[0m Showing help page $page of $max (/help <page>) \x1b[31;1m-\x1b[0m\n"; $output .= FORMAT_RED."-".FORMAT_RESET." Showing help page $page of $max (/help <page>) ".FORMAT_RED."-".FORMAT_RESET."\n";
$current = 1; $current = 1;
foreach($cmds as $c => $h){ foreach($cmds as $c => $h){
$curpage = (int) ceil($current / 5); $curpage = (int) ceil($current / 5);
@ -204,22 +207,16 @@ class ConsoleAPI{
break; break;
case "a": case "a":
case "all": case "all":
if($issuer instanceof Player) if($issuer instanceof Player){
{ if($this->server->api->ban->isOp($issuer->username)){
if($this->server->api->ban->isOp($issuer->username))
{
$output = ""; $output = "";
foreach($this->server->api->player->getAll() as $p){ foreach($this->server->api->player->getAll() as $p){
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias); $output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
} }
} }else{
else
{
$issuer->sendChat("You don't have permissions to use this command.\n"); $issuer->sendChat("You don't have permissions to use this command.\n");
} }
} }else{
else
{
$output = ""; $output = "";
foreach($this->server->api->player->getAll() as $p){ foreach($this->server->api->player->getAll() as $p){
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias); $output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
@ -319,7 +316,7 @@ class ConsoleLoop extends Thread{
public function run(){ public function run(){
if(!extension_loaded("readline")){ if(!extension_loaded("readline")){
$this->fp = fopen( "php://stdin", "r" ); $this->fp = fopen("php://stdin", "r");
} }
while($this->stop === false){ while($this->stop === false){
@ -328,7 +325,7 @@ class ConsoleLoop extends Thread{
$this->line = false; $this->line = false;
} }
if(!$this->haveReadline){ if(!extension_loaded("readline")){
@fclose($fp); @fclose($fp);
} }
exit(0); exit(0);

View File

@ -124,6 +124,7 @@ class EntityAPI{
"x" => $pos->x + mt_rand(-10, 10) / 50, "x" => $pos->x + mt_rand(-10, 10) / 50,
"y" => $pos->y + 0.19, "y" => $pos->y + 0.19,
"z" => $pos->z + mt_rand(-10, 10) / 50, "z" => $pos->z + mt_rand(-10, 10) / 50,
"level" => $pos->level,
//"speedX" => mt_rand(-3, 3) / 8, //"speedX" => mt_rand(-3, 3) / 8,
"speedY" => mt_rand(5, 8) / 2, "speedY" => mt_rand(5, 8) / 2,
//"speedZ" => mt_rand(-3, 3) / 8, //"speedZ" => mt_rand(-3, 3) / 8,

View File

@ -237,8 +237,7 @@ class LevelAPI{
} }
} }
public function getAll() public function getAll(){
{
return $this->levels; return $this->levels;
} }

View File

@ -454,6 +454,7 @@ class PlayerAPI{
"z" => $this->server->spawn->z, "z" => $this->server->spawn->z,
), ),
"inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)), "inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)),
"hotbar" => array(0, -1, -1, -1, -1, -1, -1, -1, -1),
"armor" => array_fill(0, 4, array(AIR, 0)), "armor" => array_fill(0, 4, array(AIR, 0)),
"gamemode" => $this->server->gamemode, "gamemode" => $this->server->gamemode,
"health" => 20, "health" => 20,

View File

@ -135,6 +135,7 @@ class ServerAPI{
$this->parseProperties(); $this->parseProperties();
define("DEBUG", $this->getProperty("debug", 1)); define("DEBUG", $this->getProperty("debug", 1));
define("ADVANCED_CACHE", $this->getProperty("enable-advanced-cache", false));
if($this->getProperty("port") !== false){ if($this->getProperty("port") !== false){
$this->setProperty("server-port", $this->getProperty("port")); $this->setProperty("server-port", $this->getProperty("port"));
$this->config->remove("port"); $this->config->remove("port");
@ -146,6 +147,10 @@ class ServerAPI{
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." \"".CODENAME."\" (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0); console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." \"".CODENAME."\" (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
console("[INFO] PocketMine-MP is distibuted under the LGPL License", true, true, 0); console("[INFO] PocketMine-MP is distibuted under the LGPL License", true, true, 0);
if(ADVANCED_CACHE == true){
console("[INFO] Advanced cache enabled");
}
if($this->getProperty("upnp-forwarding") === true){ if($this->getProperty("upnp-forwarding") === true){
console("[INFO] [UPnP] Trying to port forward..."); console("[INFO] [UPnP] Trying to port forward...");
UPnP_PortForward($this->getProperty("server-port")); UPnP_PortForward($this->getProperty("server-port"));
@ -290,7 +295,6 @@ class ServerAPI{
$this->server->gamemode = $this->getProperty("gamemode"); $this->server->gamemode = $this->getProperty("gamemode");
$this->server->difficulty = $this->getProperty("difficulty"); $this->server->difficulty = $this->getProperty("difficulty");
$this->server->whitelist = $this->getProperty("white-list"); $this->server->whitelist = $this->getProperty("white-list");
$this->server->reloadConfig();
} }
} }
@ -441,9 +445,11 @@ class ServerAPI{
return ($this->config->exists($name) ? $this->config->get($name):$default); return ($this->config->exists($name) ? $this->config->get($name):$default);
} }
public function setProperty($name, $value){ public function setProperty($name, $value, $save = true){
$this->config->set($name, $value); $this->config->set($name, $value);
if($save == true){
$this->writeProperties(); $this->writeProperties();
}
$this->loadProperties(); $this->loadProperties();
} }

View File

@ -52,6 +52,7 @@ class Player{
public $spawned = false; public $spawned = false;
public $inventory; public $inventory;
public $slot; public $slot;
public $hotbar;
public $armor = array(); public $armor = array();
public $loggedIn = false; public $loggedIn = false;
public $gamemode; public $gamemode;
@ -111,6 +112,7 @@ class Player{
$this->gamemode = $this->server->gamemode; $this->gamemode = $this->server->gamemode;
$this->level = $this->server->api->level->getDefault(); $this->level = $this->server->api->level->getDefault();
$this->slot = 0; $this->slot = 0;
$this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1);
$this->packetStats = array(0,0); $this->packetStats = array(0,0);
$this->server->schedule(2, array($this, "handlePacketQueues"), array(), true); $this->server->schedule(2, array($this, "handlePacketQueues"), array(), true);
$this->server->schedule(20 * 60, array($this, "clearQueue"), array(), true); $this->server->schedule(20 * 60, array($this, "clearQueue"), array(), true);
@ -251,6 +253,7 @@ class Player{
} }
} }
$this->data->set("inventory", $inv); $this->data->set("inventory", $inv);
$this->data->set("hotbar", $this->hotbar);
$armor = array(); $armor = array();
foreach($this->armor as $slot => $item){ foreach($this->armor as $slot => $item){
@ -887,7 +890,7 @@ class Player{
return false; return false;
} }
if($pos instanceof Position and $pos->level !== $this->level){ if($pos instanceof Position and $pos->level instanceof Level and $pos->level !== $this->level){
if($this->server->api->dhandle("player.teleport.level", array("player" => $this, "origin" => $this->level, "target" => $pos->level)) === false){ if($this->server->api->dhandle("player.teleport.level", array("player" => $this, "origin" => $this->level, "target" => $pos->level)) === false){
$this->entity->check = true; $this->entity->check = true;
return false; return false;
@ -1366,8 +1369,13 @@ class Player{
)); ));
if(($this->gamemode & 0x01) === 0x01){ if(($this->gamemode & 0x01) === 0x01){
$this->slot = 0; $this->slot = 0;
$this->hotbar = array();
}elseif($this->data->exists("hotbar")){
$this->hotbar = $this->data->get("hotbar");
$this->slot = $this->hotbar[0];
}else{ }else{
$this->slot = -1;//0 $this->slot = -1;//0
$this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1);
} }
$this->entity = $this->server->api->entity->add($this->level, ENTITY_PLAYER, 0, array("player" => $this)); $this->entity = $this->server->api->entity->add($this->level, ENTITY_PLAYER, 0, array("player" => $this));
$this->eid = $this->entity->eid; $this->eid = $this->entity->eid;
@ -1487,7 +1495,6 @@ class Player{
if($this->spawned === false){ if($this->spawned === false){
break; break;
} }
$data["eid"] = $this->eid; $data["eid"] = $this->eid;
$data["player"] = $this; $data["player"] = $this;
@ -1527,8 +1534,15 @@ class Player{
$data["meta"] = $data["item"]->getMetadata(); $data["meta"] = $data["item"]->getMetadata();
if($this->server->handle("player.equipment.change", $data) !== false){ if($this->server->handle("player.equipment.change", $data) !== false){
$this->slot = $data["slot"]; $this->slot = $data["slot"];
if(($this->gamemode & 0x01) === SURVIVAL){
if(!in_array($this->slot, $this->hotbar)){
array_pop($this->hotbar);
array_unshift($this->hotbar, $this->slot);
}
}
}else{ }else{
$this->sendInventorySlot($data["slot"]); //$this->sendInventorySlot($data["slot"]);
$this->sendInventory();
} }
if($this->entity->inAction === true){ if($this->entity->inAction === true){
$this->entity->inAction = false; $this->entity->inAction = false;
@ -1837,7 +1851,7 @@ class Player{
$this->entity->air = 300; $this->entity->air = 300;
$this->entity->setHealth(20, "respawn"); $this->entity->setHealth(20, "respawn");
$this->entity->updateMetadata(); $this->entity->updateMetadata();
} else { }else{
break; break;
} }
$this->sendInventory(); $this->sendInventory();
@ -2198,10 +2212,16 @@ class Player{
if(($this->gamemode & 0x01) === CREATIVE){ if(($this->gamemode & 0x01) === CREATIVE){
return; return;
} }
$hotbar = array();
foreach($this->hotbar as $slot){
$hotbar[] = $slot <= -1 ? -1 : $slot + 9;
}
$this->dataPacket(MC_CONTAINER_SET_CONTENT, array( $this->dataPacket(MC_CONTAINER_SET_CONTENT, array(
"windowid" => 0, "windowid" => 0,
"count" => count($this->inventory), "count" => count($this->inventory),
"slots" => $this->inventory, "slots" => $this->inventory,
"hotbar" => $hotbar,
)); ));
} }

View File

@ -36,7 +36,7 @@ class PocketMinecraftServer{
}*/ }*/
console("[INFO] Starting Minecraft PE server on ".($this->serverip === "0.0.0.0" ? "*":$this->serverip).":".$this->port); console("[INFO] Starting Minecraft PE server on ".($this->serverip === "0.0.0.0" ? "*":$this->serverip).":".$this->port);
define("BOOTUP_RANDOM", Utils::getRandomBytes(16)); define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID; $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->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):$this->seed;
$this->startDatabase(); $this->startDatabase();
$this->api = false; $this->api = false;
@ -65,7 +65,6 @@ class PocketMinecraftServer{
$this->tickMeasure = array_fill(0, 40, 0); $this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal"); $this->setType("normal");
$this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip); $this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip);
$this->reloadConfig();
$this->stop = false; $this->stop = false;
$this->ticks = 0; $this->ticks = 0;
if(!defined("NO_THREADS")){ if(!defined("NO_THREADS")){
@ -108,6 +107,7 @@ class PocketMinecraftServer{
} }
$this->schedule(20 * 15, array($this, "checkTicks"), array(), true); $this->schedule(20 * 15, array($this, "checkTicks"), array(), true);
$this->schedule(20 * 60, array($this, "checkMemory"), array(), true); $this->schedule(20 * 60, array($this, "checkMemory"), array(), true);
$this->schedule(20 * 45, "Cache::cleanup", array(), true);
$this->schedule(20, array($this, "asyncOperationChecker"), array(), true); $this->schedule(20, array($this, "asyncOperationChecker"), array(), true);
} }
@ -156,10 +156,6 @@ class PocketMinecraftServer{
return $result; return $result;
} }
public function reloadConfig(){
}
public function debugInfo($console = false){ public function debugInfo($console = false){
$info = array(); $info = array();
$info["tps"] = $this->getTPS(); $info["tps"] = $this->getTPS();
@ -372,46 +368,7 @@ class PocketMinecraftServer{
public function init(){ public function init(){
register_tick_function(array($this, "tick")); register_tick_function(array($this, "tick"));
console("[DEBUG] Starting internal ticker calculation", true, true, 2); declare(ticks=5000); //Minimum TPS for main thread locks
$t = 0;
while(true){
switch($t){
case 0:
declare(ticks=100);
break;
case 1:
declare(ticks=60);
break;
case 2:
declare(ticks=40);
break;
case 3:
declare(ticks=30);
break;
case 4:
declare(ticks=20);
break;
case 5:
declare(ticks=15);
break;
default:
declare(ticks=10);
break;
}
if($t > 5){
break;
}
$this->ticks = 0;
while($this->ticks < 20){
usleep(1);
}
if($this->getTPS() < 19.5){
++$t;
}else{
break;
}
}
$this->loadEvents(); $this->loadEvents();
register_shutdown_function(array($this, "dumpError")); register_shutdown_function(array($this, "dumpError"));
@ -431,10 +388,32 @@ class PocketMinecraftServer{
if($this->stop === true){ if($this->stop === true){
return; return;
} }
console("[ERROR] An Unrecovereable has ocurred and the server has Crashed. Creating an Error Dump"); 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"; $dump = "```\r\n# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
$er = error_get_last(); $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"; $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"; $dump .= "Code: \r\n";
$file = @file($er["file"], FILE_IGNORE_NEW_LINES); $file = @file($er["file"], FILE_IGNORE_NEW_LINES);
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){ for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
@ -465,7 +444,13 @@ class PocketMinecraftServer{
} }
$dump .= "\r\n\r\n"; $dump .= "\r\n\r\n";
} }
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n";
$extensions = array();
foreach(get_loaded_extensions() as $ext){
$extensions[$ext] = phpversion($ext);
}
$dump .= "Loaded Modules: ".var_export($extensions, true)."\r\n";
$dump .= "Memory Usage Tracking: \r\n".chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9)))."\r\n"; $dump .= "Memory Usage Tracking: \r\n".chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9)))."\r\n";
ob_start(); ob_start();
phpinfo(); phpinfo();
@ -474,7 +459,7 @@ class PocketMinecraftServer{
$dump .= "\r\n```"; $dump .= "\r\n```";
$name = "Error_Dump_".date("D_M_j-H.i.s-T_Y"); $name = "Error_Dump_".date("D_M_j-H.i.s-T_Y");
logg($dump, $name, true, 0, true); logg($dump, $name, true, 0, true);
console("[ERROR] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0); 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(){ public function tick(){
@ -594,6 +579,7 @@ class PocketMinecraftServer{
usleep(10000); usleep(10000);
} }
} }
$this->tick();
} }
} }
@ -643,11 +629,10 @@ class PocketMinecraftServer{
$this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT); $this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT);
$this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER); $this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER);
$this->preparedSQL->updateAction->execute(); $this->preparedSQL->updateAction->execute();
$schedule = $this->schedule[$cid]; if(!@is_callable($this->schedule[$cid][0])){
if(!is_callable($schedule[0])){
$return = false; $return = false;
}else{ }else{
$return = call_user_func($schedule[0], $schedule[1], $schedule[2]); $return = call_user_func($this->schedule[$cid][0], $this->schedule[$cid][1], $this->schedule[$cid][2]);
} }
if($action["repeat"] == 0 or $return === false){ if($action["repeat"] == 0 or $return === false){

View File

@ -1,12 +1,14 @@
#!/bin/bash #!/bin/bash
COMPILER_VERSION="0.14" COMPILER_VERSION="0.15"
PHP_VERSION="5.5.8" PHP_VERSION="5.5.8"
ZEND_VM="GOTO" ZEND_VM="GOTO"
LIBEDIT_VERSION="0.3" LIBEDIT_VERSION="0.3"
ZLIB_VERSION="1.2.8" ZLIB_VERSION="1.2.8"
PTHREADS_VERSION="0.0.45" PTHREADS_VERSION="0.1.0"
PHPYAML_VERSION="1.1.1"
YAML_VERSION="0.1.4"
CURL_VERSION="curl-7_34_0" CURL_VERSION="curl-7_34_0"
echo "[PocketMine] PHP installer and compiler for Linux & Mac" echo "[PocketMine] PHP installer and compiler for Linux & Mac"
@ -77,7 +79,7 @@ elif [ "$1" == "crosscompile" ]; then
echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac] to cross-compile" echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac] to cross-compile"
exit 1 exit 1
fi fi
else elif [ -z "$CFLAGS" ]; then
if [ `getconf LONG_BIT` = "64" ]; then if [ `getconf LONG_BIT` = "64" ]; then
echo "[INFO] Compiling for current machine using 64-bit" echo "[INFO] Compiling for current machine using 64-bit"
CFLAGS="-m64 $CFLAGS" CFLAGS="-m64 $CFLAGS"
@ -95,24 +97,22 @@ type $CC >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"$CC\
[ -z "$CFLAGS" ] && CFLAGS=""; [ -z "$CFLAGS" ] && CFLAGS="";
[ -z "$CONFIGURE_FLAGS" ] && CONFIGURE_FLAGS=""; [ -z "$CONFIGURE_FLAGS" ] && CONFIGURE_FLAGS="";
$CC -O3 -march=$march -mtune=$mtune -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1 $CC -O2 -pipe -march=$march -mtune=$mtune -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
$CC -O3 -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1 $CC -O2 -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
export CFLAGS="-O3 -fno-gcse " export CFLAGS="-O2 -fno-gcse "
else else
export CFLAGS="-O3 -fno-gcse $CFLAGS" export CFLAGS="-O2 -fno-gcse $CFLAGS"
fi fi
else else
export CFLAGS="-O3 -march=$march -mtune=$mtune -fno-gcse $CFLAGS" export CFLAGS="-O2 -pipe -march=$march -mtune=$mtune -fno-gcse $CFLAGS"
fi fi
rm -r -f install_data/ >> "$DIR/install.log" 2>&1 rm -r -f install_data/ >> "$DIR/install.log" 2>&1
rm -r -f php5/ >> "$DIR/install.log" 2>&1
rm -r -f bin/ >> "$DIR/install.log" 2>&1 rm -r -f bin/ >> "$DIR/install.log" 2>&1
mkdir -m 0777 install_data >> "$DIR/install.log" 2>&1 mkdir -m 0777 install_data >> "$DIR/install.log" 2>&1
mkdir -m 0777 php5 >> "$DIR/install.log" 2>&1
mkdir -m 0777 bin >> "$DIR/install.log" 2>&1 mkdir -m 0777 bin >> "$DIR/install.log" 2>&1
cd install_data cd install_data
set -e set -e
@ -207,6 +207,28 @@ wget http://pecl.php.net/get/pthreads-$PTHREADS_VERSION.tgz --no-check-certifica
mv pthreads-$PTHREADS_VERSION "$DIR/install_data/php/ext/pthreads" mv pthreads-$PTHREADS_VERSION "$DIR/install_data/php/ext/pthreads"
echo " done!" echo " done!"
#PHP YAML
echo -n "[PHP YAML] downloading $PHPYAML_VERSION..."
wget http://pecl.php.net/get/yaml-$PHPYAML_VERSION.tgz --no-check-certificate -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv yaml-$PHPYAML_VERSION "$DIR/install_data/php/ext/yaml"
echo " done!"
#YAML
echo -n "[YAML] downloading $YAML_VERSION..."
wget http://pyyaml.org/download/libyaml/yaml-$YAML_VERSION.tar.gz -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv yaml-$YAML_VERSION yaml
echo -n " checking..."
cd yaml
RANLIB=$RANLIB ./configure --prefix="$DIR/install_data/php/ext/yaml" \
--enable-static --disable-shared >> "$DIR/install.log" 2>&1
echo -n " compiling..."
make -j $THREADS >> "$DIR/install.log" 2>&1
echo -n " installing..."
make install >> "$DIR/install.log" 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./yaml
echo " done!"
echo -n "[PHP]" echo -n "[PHP]"
set +e set +e
@ -234,11 +256,12 @@ if [ "$1" == "crosscompile" ]; then
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no" CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no"
fi fi
./configure $OPTIMIZATION--prefix="$DIR/php5" \ ./configure $OPTIMIZATION--prefix="$DIR/bin/php5" \
--exec-prefix="$DIR/php5" \ --exec-prefix="$DIR/bin/php5" \
--with-curl="$HAVE_CURL" \ --with-curl="$HAVE_CURL" \
--with-zlib="$DIR/install_data/php/ext/zlib" \ --with-zlib="$DIR/install_data/php/ext/zlib" \
--with-zlib-dir="$DIR/install_data/php/ext/zlib" \ --with-zlib-dir="$DIR/install_data/php/ext/zlib" \
--with-yaml="$DIR/install_data/php/ext/yaml" \
$HAVE_LIBEDIT \ $HAVE_LIBEDIT \
--disable-libxml \ --disable-libxml \
--disable-xml \ --disable-xml \
@ -263,6 +286,7 @@ $HAVE_LIBEDIT \
--enable-pthreads \ --enable-pthreads \
--enable-maintainer-zts \ --enable-maintainer-zts \
--enable-zend-signals \ --enable-zend-signals \
--with-mysqli=mysqlnd \
--enable-embedded-mysqli \ --enable-embedded-mysqli \
--enable-bcmath \ --enable-bcmath \
--enable-cli \ --enable-cli \
@ -280,8 +304,6 @@ echo " done!"
cd "$DIR" cd "$DIR"
echo -n "[INFO] Cleaning up..." echo -n "[INFO] Cleaning up..."
rm -r -f install_data/ >> "$DIR/install.log" 2>&1 rm -r -f install_data/ >> "$DIR/install.log" 2>&1
mv php5/bin/php bin/php
rm -r -f php5/ >> "$DIR/install.log" 2>&1
date >> "$DIR/install.log" 2>&1 date >> "$DIR/install.log" 2>&1
echo " done!" echo " done!"
echo "[PocketMine] You should start the server now using \"./start.sh.\"" echo "[PocketMine] You should start the server now using \"./start.sh.\""

View File

@ -25,6 +25,8 @@ date_default_timezone_set("GMT");
if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){ if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){
$time = time(); $time = time();
$time -= $time % 60; $time -= $time % 60;
//TODO: Parse different time & date formats by region. ¬¬ world
//Example: USA
exec("time.exe /T", $hour); exec("time.exe /T", $hour);
$i = array_map("intval", explode(":", trim($hour[0]))); $i = array_map("intval", explode(":", trim($hour[0])));
exec("date.exe /T", $date); exec("date.exe /T", $date);
@ -37,10 +39,6 @@ if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){
$daylight = (int) date("I"); $daylight = (int) date("I");
if($daylight === 0){
$offset -= 3600;
}
date_default_timezone_set(timezone_name_from_abbr("", $offset, $daylight)); date_default_timezone_set(timezone_name_from_abbr("", $offset, $daylight));
gc_enable(); gc_enable();

View File

@ -54,6 +54,15 @@ if(!extension_loaded("sockets") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"")
if(!extension_loaded("pthreads") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "pthreads." . PHP_SHLIB_SUFFIX) === false){ if(!extension_loaded("pthreads") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "pthreads." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the pthreads extension.", true, true, 0); console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
++$errors; ++$errors;
}else{
$pthreads_version = phpversion("pthreads");
if(substr_count($pthreads_version, ".") < 2){
$pthreads_version = "0.$pthreads_version";
}
if(version_compare($pthreads_version, "0.1.0") < 0){
console("[ERROR] pthreads >= 0.1.0 is required, while you have $pthreads_version.", true, true, 0);
++$errors;
}
} }
if(!extension_loaded("curl") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "curl." . PHP_SHLIB_SUFFIX) === false){ if(!extension_loaded("curl") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "curl." . PHP_SHLIB_SUFFIX) === false){
@ -66,13 +75,18 @@ if(!extension_loaded("sqlite3") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"")
++$errors; ++$errors;
} }
if(!extension_loaded("yaml") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "yaml." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the YAML extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "zlib." . PHP_SHLIB_SUFFIX) === false){ if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "zlib." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the Zlib extension.", true, true, 0); console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
++$errors; ++$errors;
} }
if($errors > 0){ if($errors > 0){
console("[ERROR] Please use the installer provided on the homepage.", true, true, 0); console("[ERROR] Please use the installer provided on the homepage, or recompile PHP again.", true, true, 0);
exit(1); //Exit with error exit(1); //Exit with error
} }

View File

@ -192,6 +192,7 @@ function console($message, $EOL = true, $log = true, $level = 1){
if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){ if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){
switch($matches[1]){ switch($matches[1]){
case "ERROR": case "ERROR":
case "SEVERE":
$add .= FORMAT_RED; $add .= FORMAT_RED;
break; break;
case "INTERNAL": case "INTERNAL":

View File

@ -3,22 +3,22 @@ skip_installer=설치 마법사를 건너뛰겠습니까?
welcome_to_pocketmine=PocketMine-MP에 오신 것을 환영합니다!\n서버 설치를 시작하기 전, 약관에 동의해야 합니다. \nPocketMine-MP는 GNU 약소 일반 공중 사용 허가서(LGPL) 하에 배포되고 있습니다. \n이 폴더에서 약관을 읽을 수 있습니다. welcome_to_pocketmine=PocketMine-MP에 오신 것을 환영합니다!\n서버 설치를 시작하기 전, 약관에 동의해야 합니다. \nPocketMine-MP는 GNU 약소 일반 공중 사용 허가서(LGPL) 하에 배포되고 있습니다. \n이 폴더에서 약관을 읽을 수 있습니다.
accept_license=약관에 동의하십니까? accept_license=약관에 동의하십니까?
you_have_to_accept_the_license=GNU 약소 일반 공중 사용 허가서(LGPL)에 동의해야 PocketMine-MP를 사용할 수 있습니다 you_have_to_accept_the_license=GNU 약소 일반 공중 사용 허가서(LGPL)에 동의하셔야 PocketMine-MP를 사용할 수 있습니다.
setting_up_server_now=서버 설정을 시작합니다. setting_up_server_now=서버 설정을 시작합니다.
default_values_info=기본값을 수정하고 싶지 않으면, 엔터를 누르십시. default_values_info=기본값을 수정하고 싶지 않으면, 엔터를 누르십시기 바랍니다.
server_properties=이 설정들은 server.properties 파일에서 세부적으로 변경할 수 있습니다. server_properties=이 설정들은 server.properties 파일에서 세부적으로 변경이 가능합니다.
name_your_server=당신의 서버 이름을 입력하십시오 name_your_server=당신의 서버 이름을 입력하시기 바랍니다.
port_warning=만약 당신이 서버를 처음 설정한다면 포트 값을 변경하지 마십시오. port_warning=만약 당신이 서버를 처음 설정한다면 포트 값을 변경하지 마세요.
server_port=서버 포트 server_port=서버 포트
invalid_port=서버 포트가 잘못 입력되었습니다 invalid_port=서버 포트가 잘못 입력되었습니다.
ram_warning=RAM 값은 PocketMine-MP에 할당할 메모리의 크기입니다. 128~256MB를 권장합니다. ram_warning=RAM 값은 PocketMine-MP에 할당할 메모리의 크기입니다. 128~256MB를 권장합니다.
server_ram=서버 RAM (MB) server_ram=서버 RAM (MB)
gamemode_info=크리에이티브 (1) 또는 서바이벌 (0) 게임모드 중 하나를 고르십시오 gamemode_info=크리에이티브 (1) 또는 서바이벌 (0) 게임모드 중 하나를 고르세요.
default_gamemode=기본 게임 모드 default_gamemode=기본 게임 모드
max_players=최대 동시 접속 인원 수 max_players=최대 동시 접속 인원 수
spawn_protection_info=스폰 보호는 OP를 제외한 유저들이 스폰 지역 근처에서 블럭을 놓거나 부수는것을 방지합니다 spawn_protection_info=스폰 보호는 OP를 제외한 유저들이 스폰 지역 근처에서 블럭을 놓거나 부수는것을 방지합니다.
spawn_protection=스폰 지역 보호를 사용하겠습니까? spawn_protection=스폰 지역 보호를 사용하겠습니까?
op_info=OP는 서버 관리자를 뜻합니다. OP는 일반 플레이어보다 훨씬 많은 명령어들을 사용할 수 있습니다 op_info=OP는 서버 관리자를 뜻합니다. OP는 일반 플레이어보다 훨씬 많은 명령어들을 사용할 수 있습니다

View File

@ -25,7 +25,7 @@ op_info=Een OP is de beheerder van de server. OP's kunnen meer commando's gebrui
op_who=OP speler naam (voorbeeld: je username) op_who=OP speler naam (voorbeeld: je username)
op_warning=Je kunt later meerdere OP's toevoegen met het commando /op <player> op_warning=Je kunt later meerdere OP's toevoegen met het commando /op <player>
whitelist_info=De whitelist laat alleen de spelers die in de lijst staan op de server. whitelist_info=De whitelist laat alleen de spelers die in de lijst staan op de server.
whitelist_enable=Wil je de white-list aanzetten? whitelist_enable=Wil je de whitelist aanzetten?
whitelist_warning=Je moet wel spelers aan de whitelist toevoegen. whitelist_warning=Je moet wel spelers aan de whitelist toevoegen.
query_warning1=Query is een protocol dat gebruikt wordt door verschillende programma's om informatie te verkrijgen van je server en welke spelers ingelogd zijn. query_warning1=Query is een protocol dat gebruikt wordt door verschillende programma's om informatie te verkrijgen van je server en welke spelers ingelogd zijn.
@ -41,5 +41,5 @@ ip_warning=Je externe IP is {{EXTERNAL_IP}}. Het is mogelijk dat je moet port-fo
ip_confirm=Wees niet bang om het te controleren, als je moet port-forwarden en je slaat dit over, kunnen externe spelers niet op de server. ip_confirm=Wees niet bang om het te controleren, als je moet port-forwarden en je slaat dit over, kunnen externe spelers niet op de server.
you_have_finished=Je hebt de set-up help volledig beëindigd. you_have_finished=Je hebt de set-up help volledig beëindigd.
pocketmine_will_start=PocketMine-MP zal nu starten. Type /help om een lijst met alle beschikbare commando's te zien. pocketmine_will_start=PocketMine-MP zal nu opstarten. Type /help om de lijst van beschikbare commando's te weergeven.
pocketmine_plugins=Check de Plugin Opslag om nieuwe features, minigames of geavanceerde spawnbeveiliging toe te voegen aan je server pocketmine_plugins=Check de Plugin Opslag om nieuwe features, minigames of geavanceerde spawnbeveiliging toe te voegen aan je server

View File

@ -0,0 +1,6 @@

View File

@ -26,7 +26,7 @@ op_who=OP的用户名是什么?
op_warning=你可以执行\"/op <用户名>\"来添加OP. op_warning=你可以执行\"/op <用户名>\"来添加OP.
whitelist_info=白名单可以只允许在其列表内的玩家加入. whitelist_info=白名单可以只允许在其列表内的玩家加入.
whitelist_enable=您想启用白名单吗? whitelist_enable=您想启用白名单吗?
whitelist_warning=你可以用\"/whitelist add <用户名>\"把别人加入白名单. whitelist_warning=你可以用"/whitelist add <用户名>"把别人加入白名单.
query_warning1=请求是一个用于不同的程序的协议用来获取您服务器数据和登录的玩家. query_warning1=请求是一个用于不同的程序的协议用来获取您服务器数据和登录的玩家.
query_warning2=如果您禁止了它, 您将不能使用服务器列表. query_warning2=如果您禁止了它, 您将不能使用服务器列表.

View File

@ -99,7 +99,7 @@ class LavaBlock extends LiquidBlock{
$b = $this->getSide($side); $b = $this->getSide($side);
if($b instanceof LavaBlock){ if($b instanceof LavaBlock){
}else if($b->isFlowable === true){ }elseif($b->isFlowable === true){
$this->level->setBlock($b, new LavaBlock( min($level + 2,7) ), false, false, true); $this->level->setBlock($b, new LavaBlock( min($level + 2,7) ), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL); ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
} }

View File

@ -30,6 +30,7 @@ class SlabBlock extends TransparentBlock{
4 => "Brick", 4 => "Brick",
5 => "Stone Brick", 5 => "Stone Brick",
6 => "Quartz", 6 => "Quartz",
7 => "",
); );
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab"; $this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab";
if(($this->meta & 0x08) === 0x08){ if(($this->meta & 0x08) === 0x08){

View File

@ -55,6 +55,8 @@ class RCON{
for($n = 0; $n < $this->threads; ++$n){ for($n = 0; $n < $this->threads; ++$n){
$this->workers[$n]->close(); $this->workers[$n]->close();
$this->workers[$n]->join(); $this->workers[$n]->join();
usleep(50000);
$this->workers[$n]->kill();
} }
@socket_close($this->socket); @socket_close($this->socket);
$this->threads = 0; $this->threads = 0;

View File

@ -800,12 +800,29 @@ class CustomPacketHandler{
for($s = 0; $s < $this->data["count"] and !$this->feof(); ++$s){ for($s = 0; $s < $this->data["count"] and !$this->feof(); ++$s){
$this->data["slots"][$s] = Utils::readSlot($this); $this->data["slots"][$s] = Utils::readSlot($this);
} }
if($this->data["windowid"] == 0){
$slots = min(9, Utils::readShort($this->get(2), false));
$this->data["hotbar"] = array();
if($slots > 0){
for($s = 0; $s < $slots; ++$s){
$this->data["hotbar"][$s] = Utils::readInt($this->get(4));
}
}
}
}else{ }else{
$this->raw .= chr($this->data["windowid"]); $this->raw .= chr($this->data["windowid"]);
$this->raw .= Utils::writeShort(count($this->data["slots"])); $this->raw .= Utils::writeShort(count($this->data["slots"]));
foreach($this->data["slots"] as $slot){ foreach($this->data["slots"] as $slot){
$this->raw .= Utils::writeSlot($slot); $this->raw .= Utils::writeSlot($slot);
} }
if($this->data["windowid"] == 0 and isset($this->data["hotbar"])){
if(count($this->data["hotbar"]) > 0){
$this->raw .= Utils::writeShort(count($this->data["hotbar"]));
foreach($this->data["hotbar"] as $slot){
$this->raw .= Utils::writeInt($slot);
}
}
}
} }
break; break;
case MC_CONTAINER_SET_DATA: case MC_CONTAINER_SET_DATA:

View File

@ -467,14 +467,15 @@ class PMFLevel extends PMF{
++$this->chunkChange[$index][$Y]; ++$this->chunkChange[$index][$Y];
} }
$this->chunkChange[$index][-1] = true; $this->chunkChange[$index][-1] = true;
if($old_b instanceof LiquidBlock) if($old_b instanceof LiquidBlock){
{
$pos = new Position($x, $y, $z, $this->level); $pos = new Position($x, $y, $z, $this->level);
for($side = 0; $side <= 5; ++$side) for($side = 0; $side <= 5; ++$side){
{
$b = $pos->getSide($side); $b = $pos->getSide($side);
if($b instanceof LavaBlock) { ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL); } if($b instanceof LavaBlock){
else { ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL); } ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
}else{
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
} }
} }
return true; return true;

53
src/utils/Cache.php Normal file
View File

@ -0,0 +1,53 @@
<?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/
*
*
*/
class Cache{
public static $cached = array();
public static function add($identifier, $blob, $minTTL = 30){
self::$cached[$identifier] = array($blob, microtime(true) + $minTTL);
}
public static function get($identifier){
if(isset(self::$cached[$identifier])){
return self::$cached[$identifier][0];
}
return false;
}
public static function exists($identifier){
return isset(self::$cached[$identifier]);
}
public static function remove($identifier){
unset(self::$cached[$identifier]);
}
public static function cleanup(){
$time = microtime(true);
foreach(self::$cached as $index => $data){
if($data[1] < $time){
unset(self::$cached[$index]);
}
}
}
}

View File

@ -87,6 +87,10 @@ class Config{
$correct = $this->check(); $correct = $this->check();
} }
public function fixYAMLIndexes($str){
return preg_replace("#^([ ]*)([a-zA-Z_]{1}[^\:]*)\:#m", "$1\"$2\":", $str);
}
/** /**
* @param string $file * @param string $file
* @param int $type * @param int $type
@ -125,7 +129,8 @@ class Config{
$this->config = @json_decode($content, true); $this->config = @json_decode($content, true);
break; break;
case CONFIG_YAML: case CONFIG_YAML:
$this->config = Spyc::YAMLLoad($content); $content = $this->fixYAMLIndexes($content);
$this->config = yaml_parse($content);
break; break;
case CONFIG_SERIALIZED: case CONFIG_SERIALIZED:
$this->config = @unserialize($content); $this->config = @unserialize($content);
@ -172,7 +177,7 @@ class Config{
$content = json_encode($this->config, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING); $content = json_encode($this->config, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING);
break; break;
case CONFIG_YAML: case CONFIG_YAML:
$content = Spyc::YAMLDump($this->config); $content = yaml_emit($this->config, YAML_UTF8_ENCODING);
break; break;
case CONFIG_SERIALIZED: case CONFIG_SERIALIZED:
$content = @serialize($this->config); $content = @serialize($this->config);
@ -256,13 +261,13 @@ class Config{
* @return boolean * @return boolean
*/ */
public function exists($k, $lowercase = false){ public function exists($k, $lowercase = false){
if($lowercase === true)://Take this ridiculously retarded IF formatting! - @sekjun98888877777778888888888888 if($lowercase === true){
$k = strtolower($k);//Convert requested key to lower $k = strtolower($k);//Convert requested key to lower
$array = array_change_key_case($this->config, CASE_LOWER);//Change all keys in array to lower $array = array_change_key_case($this->config, CASE_LOWER);//Change all keys in array to lower
return isset($array[$k]);//Find $k in modified array return isset($array[$k]);//Find $k in modified array
else: }else{
return isset($this->config[$k]); return isset($this->config[$k]);
endif; }
} }
/** /**

View File

@ -64,57 +64,3 @@ class Java_String{
return $h; return $h;
} }
} }
class Java_Random{
private $haveNextNextGaussian, $nextNextGaussian, $seed, $n1, $n2, $n3, $zero;
public function __construct($seed = false){
$this->n1 = new Math_BigInteger(0x5DEECE66D);
$this->n2 = new Math_BigInteger(1);
$this->n2 = $this->n2->bitwise_leftShift(48)->subtract($this->n2);
$this->n3 = new Math_BigInteger(0xB);
$this->zero = new Math_BigInteger(0);
if($seed === false){
$seed = microtime(true) * 1000000;
}
$this->setSeed($seed);
}
public function setSeed($seed){
$seed = new Math_BigInteger($seed);
$this->seed = $seed->bitwise_xor($this->n1)->bitwise_and($this->n2);
$this->haveNextNextGaussian = false;
}
protected function next($bits){
$bits = (int) $bits;
$this->seed = $this->seed->multiply($this->n1)->add($this->n3)->bitwise_and($this->n2);
return $this->_tripleRightShift($this->seed, (48 - $bits));
}
private function _tripleRightShift($number, $places){
if($number->compare($this->zero) >= 0){
return $number->bitwise_rightShift($places);
}
$n1 = new Math_BigInteger(2);
return $number->bitwise_rightShift($places)->add($n1->bitwise_leftShift(~$places));
}
public function nextBytes($bytes){
$bytes = (int) $bytes;
$b = b"";
$max = $bytes & ~0x3;
for($i = 0; $i < $max; $i += 4){
$b .= $this->next(32)->toBytes();
}
if($max < $bytes){
$random = $this->next(32)->toBytes();
for($j = $max; $j < $bytes; ++$j){
$b .= $random{$j-$max};
}
}
return $b;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,33 @@ class Utils{
return ((@fsockopen("google.com", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.linux.org", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.php.net", 80, $e = null, $n = null, 2) !== false) ? true:false); return ((@fsockopen("google.com", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.linux.org", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.php.net", 80, $e = null, $n = null, 2) !== false) ? true:false);
} }
public static function getUniqueID($raw = false, $extra = ""){
$machine = php_uname("a");
$machine .= file_exists("/proc/cpuinfo") ? file_get_contents("/proc/cpuinfo") : "";
$machine .= sys_get_temp_dir();
$machine .= $extra;
if(Utils::getOS() == "win"){
exec("ipconfig /ALL", $mac);
$mac = implode("\n", $mac);
if(preg_match_all("#Physical Address[. ]{1,}: ([0-9A-F\-]{17})#", $mac, $matches)){
foreach($matches[1] as $i => $v){
if($v == "00-00-00-00-00-00"){
unset($matches[1][$i]);
}
}
$machine .= implode(" ", $matches[1]); //Mac Addresses
}
}
$data = $machine . PHP_MAXPATHLEN;
$data .= PHP_INT_MAX;
$data .= PHP_INT_SIZE;
$data .= get_current_user();
foreach(get_loaded_extensions() as $ext){
$data .= $ext.":".phpversion($ext);
}
return hash("md5", $machine, $raw).hash("sha512", $data, $raw);
}
public static function getIP($force = false){ public static function getIP($force = false){
if(Utils::$online === false){ if(Utils::$online === false){
return false; return false;

View File

@ -144,6 +144,9 @@ class Entity extends Position{
} }
$this->updateLast(); $this->updateLast();
$this->updatePosition(); $this->updatePosition();
if($this->y < 0 and $this->class !== ENTITY_PLAYER){
$this->close();
}
} }
public function updateFuse(){ public function updateFuse(){
@ -598,7 +601,7 @@ class Entity extends Position{
public function getDirection(){ public function getDirection(){
$rotation = ($this->yaw - 90) % 360; $rotation = ($this->yaw - 90) % 360;
if ($rotation < 0) { if($rotation < 0) {
$rotation += 360.0; $rotation += 360.0;
} }
if((0 <= $rotation and $rotation < 45) or (315 <= $rotation and $rotation < 360)){ if((0 <= $rotation and $rotation < 45) or (315 <= $rotation and $rotation < 360)){
@ -820,7 +823,7 @@ class Entity extends Position{
} }
public function setPosition(Vector3 $pos, $yaw = false, $pitch = false){ public function setPosition(Vector3 $pos, $yaw = false, $pitch = false){
if($pos instanceof Position and $this->level !== $pos->level){ if($pos instanceof Position and $pos->level instanceof Level and $this->level !== $pos->level){
$this->level = $pos->level; $this->level = $pos->level;
$this->server->preparedSQL->entity->setLevel->reset(); $this->server->preparedSQL->entity->setLevel->reset();
$this->server->preparedSQL->entity->setLevel->clear(); $this->server->preparedSQL->entity->setLevel->clear();

View File

@ -299,6 +299,9 @@ class Level{
} }
$block->position($pos); $block->position($pos);
$i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4); $i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4);
if(ADVANCED_CACHE == true){
Cache::remove("world:{$this->name}:".($pos->x >> 4).":".($pos->z >> 4));
}
if(!isset($this->changedBlocks[$i])){ if(!isset($this->changedBlocks[$i])){
$this->changedBlocks[$i] = array(); $this->changedBlocks[$i] = array();
$this->changedCount[$i] = 0; $this->changedCount[$i] = 0;
@ -336,6 +339,9 @@ class Level{
$this->changedBlocks[$i] = array(); $this->changedBlocks[$i] = array();
$this->changedCount[$i] = 0; $this->changedCount[$i] = 0;
} }
if(ADVANCED_CACHE == true){
Cache::remove("world:{$this->name}:".($pos->x >> 4).":".($pos->z >> 4));
}
$this->changedBlocks[$i][] = clone $block; $this->changedBlocks[$i][] = clone $block;
++$this->changedCount[$i]; ++$this->changedCount[$i];
} }
@ -365,6 +371,9 @@ class Level{
return false; return false;
} }
$this->changedCount[$X.":".$Y.":".$Z] = 4096; $this->changedCount[$X.":".$Y.":".$Z] = 4096;
if(ADVANCED_CACHE == true){
Cache::remove("world:{$this->name}:$X:$Z");
}
return $this->level->setMiniChunk($X, $Z, $Y, $data); return $this->level->setMiniChunk($X, $Z, $Y, $data);
} }
@ -379,13 +388,22 @@ class Level{
if(!isset($this->level)){ if(!isset($this->level)){
return false; return false;
} }
return $this->level->unloadChunk($X, $Z); Cache::remove("world:{$this->name}:$X:$Z");
return $this->level->unloadChunk($X, $Z, $this->server->saveEnabled);
} }
public function getOrderedChunk($X, $Z, $Yndex){ public function getOrderedChunk($X, $Z, $Yndex){
if(!isset($this->level)){ if(!isset($this->level)){
return false; return false;
} }
if(ADVANCED_CACHE == true and $Yndex == 0xff){
$identifier = "world:{$this->name}:$X:$Z";
if(($cache = Cache::get($identifier)) !== false){
return $cache;
}
}
$raw = array(); $raw = array();
for($Y = 0; $Y < 8; ++$Y){ for($Y = 0; $Y < 8; ++$Y){
if(($Yndex & (1 << $Y)) > 0){ if(($Yndex & (1 << $Y)) > 0){
@ -401,6 +419,9 @@ class Level{
$ordered .= substr($mini, $j << 5, 24); //16 + 8 $ordered .= substr($mini, $j << 5, 24); //16 + 8
} }
} }
if(ADVANCED_CACHE == true and $Yndex == 0xff){
Cache::add($identifier, $ordered, 60);
}
return $ordered; return $ordered;
} }
@ -434,7 +455,10 @@ class Level{
$z = (int) round($spawn->z); $z = (int) round($spawn->z);
for(; $y > 0; --$y){ for(; $y > 0; --$y){
$v = new Vector3($x, $y, $z); $v = new Vector3($x, $y, $z);
if(!($this->getBlock($v->getSide(0)) instanceof AirBlock)){ $b = $this->getBlock($v->getSide(0));
if($b === false){
return $spawn;
}elseif(!($b instanceof AirBlock)){
break; break;
} }
} }

View File

@ -234,7 +234,7 @@ class Tile extends Position{
$raw = $this->getSlot(0); $raw = $this->getSlot(0);
$product = $this->getSlot(2); $product = $this->getSlot(2);
$smelt = $raw->getSmeltItem(); $smelt = $raw->getSmeltItem();
$canSmelt = $smelt !== false and $raw->count > 0 and (($product->getID() === $smelt->getID() and $product->getMetadata() === $smelt->getMetadata() and $product->count < $product->getMaxStackSize()) or $product->getID() === AIR); $canSmelt = ($smelt !== false and $raw->count > 0 and (($product->getID() === $smelt->getID() and $product->getMetadata() === $smelt->getMetadata() and $product->count < $product->getMaxStackSize()) or $product->getID() === AIR));
if($this->data["BurnTime"] <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->count > 0){ if($this->data["BurnTime"] <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->count > 0){
$this->lastUpdate = microtime(true); $this->lastUpdate = microtime(true);
$this->data["MaxTime"] = $this->data["BurnTime"] = floor($fuel->getFuelTime() * 20); $this->data["MaxTime"] = $this->data["BurnTime"] = floor($fuel->getFuelTime() * 20);

View File

@ -64,17 +64,17 @@ class PineTreeObject extends TreeObject{
$firstMaxedRadius = false; $firstMaxedRadius = false;
for($leavesY = 0; $leavesY <= $leavesBottomY; ++$leavesY) { for($leavesY = 0; $leavesY <= $leavesBottomY; ++$leavesY) {
$yy = $this->totalHeight - $leavesY; $yy = $this->totalHeight - $leavesY;
for ($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) { for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) {
for ($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) { for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) {
if (abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) { if(abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) {
$level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new LeavesBlock($this->type)); $level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new LeavesBlock($this->type));
} }
} }
} }
if ($leavesRadius >= $leavesMaxRadius) { if($leavesRadius >= $leavesMaxRadius) {
$leavesRadius = $firstMaxedRadius ? 1 : 0; $leavesRadius = $firstMaxedRadius ? 1 : 0;
$firstMaxedRadius = true; $firstMaxedRadius = true;
if (++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius) { if(++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius) {
$leavesMaxRadius = $this->leavesAbsoluteMaxRadius; $leavesMaxRadius = $this->leavesAbsoluteMaxRadius;
} }
}else{ }else{

View File

@ -36,7 +36,7 @@ class SmallTreeObject extends TreeObject{
public function canPlaceObject(Level $level, Vector3 $pos, Random $random){ public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$radiusToCheck = 0; $radiusToCheck = 0;
for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) { for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) {
if ($yy == 1 or $yy === $this->trunkHeight) { if($yy == 1 or $yy === $this->trunkHeight) {
++$radiusToCheck; ++$radiusToCheck;
} }
for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){
@ -94,7 +94,7 @@ class SmallTreeObject extends TreeObject{
} }
// Place the trunk last // Place the trunk last
if( $leaflevel > 1 ) if($leaflevel > 1)
{ {
$trunkpos = new Vector3( $pos->x, $pos->y + $yy, $pos->z ); $trunkpos = new Vector3( $pos->x, $pos->y + $yy, $pos->z );
$level->setBlockRaw($trunkpos, new WoodBlock( $this->type ) ); $level->setBlockRaw($trunkpos, new WoodBlock( $this->type ) );

View File

@ -62,7 +62,7 @@ class SpruceTreeObject extends TreeObject{
for($yy = $this->totalHeight; $yy >= $this->leavesBottomY; --$yy){ for($yy = $this->totalHeight; $yy >= $this->leavesBottomY; --$yy){
for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) { for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) {
for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) { for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) {
if (abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) { if(abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) {
$level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new LeavesBlock($this->type)); $level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new LeavesBlock($this->type));
} }
} }

View File

@ -1,14 +1,9 @@
#!/bin/bash #!/bin/bash
DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
cd "$DIR" cd "$DIR"
if [ -f ./php5/bin/php ]; then if [ -f ./bin/php5/bin/php ]; then
mkdir -m 0777 bin/ exec ./bin/php5/bin/php -d enable_dl=On PocketMine-MP.php $@
mv ./php5/bin/php ./bin/php
rm -r -f ./php5/
fi
if [ -f ./bin/php ]; then
./bin/php -d enable_dl=On PocketMine-MP.php $@
else else
echo "[WARNING] You are not using the standalone PocketMine-MP PHP binary." echo "[WARNING] You are not using the standalone PocketMine-MP PHP binary."
php -d enable_dl=On PocketMine-MP.php $@ exec php -d enable_dl=On PocketMine-MP.php $@
fi fi