diff --git a/.travis.yml b/.travis.yml index e06c9f64c..b2032b9dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,11 @@ language: php php: - - 5.4 + - 5.5 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: - php src/tests/ServerSuiteTest.php --no-wizard diff --git a/README.md b/README.md index 331b5f9db..6cf37d3c4 100644 --- a/README.md +++ b/README.md @@ -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 SQLite3](http://php.net/manual/en/book.sqlite3.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. -* __[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 pthreads](http://pthreads.org/)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything. +* __[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 * __[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 diff --git a/src/API/BanAPI.php b/src/API/BanAPI.php index 1ee8821ea..0c5d6f3ea 100644 --- a/src/API/BanAPI.php +++ b/src/API/BanAPI.php @@ -145,6 +145,10 @@ class BanAPI{ break; case "op": $user = strtolower($params[0]); + if($user == NULL){ + $output .= "Usage: /op \n"; + break; + } $player = $this->server->api->player->get($user); if(!($player instanceof Player)){ $this->ops->set($user); @@ -358,10 +362,8 @@ class BanAPI{ return true; }elseif($this->bannedIPs->exists($ip, true)){ return true; - } - else - { - return false; + }else{ + return false; } } @@ -376,10 +378,8 @@ class BanAPI{ return true; }elseif($this->banned->exists($username, true)){ return true; - } - else - { - return false; + }else{ + return false; } } diff --git a/src/API/ConsoleAPI.php b/src/API/ConsoleAPI.php index 87d25de4a..0ac1583e6 100644 --- a/src/API/ConsoleAPI.php +++ b/src/API/ConsoleAPI.php @@ -47,6 +47,9 @@ class ConsoleAPI{ if(!defined("NO_THREADS")){ $this->loop->stop(); $this->loop->notify(); + //@fclose($this->loop->fp); + usleep(50000); + $this->loop->kill(); //$this->loop->join(); } } @@ -128,7 +131,7 @@ class ConsoleAPI{ $max = ceil(count($cmds) / 5); $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 ) \x1b[31;1m-\x1b[0m\n"; + $output .= FORMAT_RED."-".FORMAT_RESET." Showing help page $page of $max (/help ) ".FORMAT_RED."-".FORMAT_RESET."\n"; $current = 1; foreach($cmds as $c => $h){ $curpage = (int) ceil($current / 5); @@ -204,22 +207,16 @@ class ConsoleAPI{ break; case "a": case "all": - if($issuer instanceof Player) - { - if($this->server->api->ban->isOp($issuer->username)) - { + if($issuer instanceof Player){ + if($this->server->api->ban->isOp($issuer->username)){ $output = ""; 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); } - } - else - { + }else{ $issuer->sendChat("You don't have permissions to use this command.\n"); } - } - else - { + }else{ $output = ""; 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); @@ -294,7 +291,7 @@ class ConsoleLoop extends Thread{ public $stop; public $base; public $ev; - public $fp; + public $fp; public function __construct(){ $this->line = false; $this->stop = false; @@ -319,7 +316,7 @@ class ConsoleLoop extends Thread{ public function run(){ if(!extension_loaded("readline")){ - $this->fp = fopen( "php://stdin", "r" ); + $this->fp = fopen("php://stdin", "r"); } while($this->stop === false){ @@ -328,7 +325,7 @@ class ConsoleLoop extends Thread{ $this->line = false; } - if(!$this->haveReadline){ + if(!extension_loaded("readline")){ @fclose($fp); } exit(0); diff --git a/src/API/EntityAPI.php b/src/API/EntityAPI.php index 9e2403f01..5e8140e31 100644 --- a/src/API/EntityAPI.php +++ b/src/API/EntityAPI.php @@ -124,6 +124,7 @@ class EntityAPI{ "x" => $pos->x + mt_rand(-10, 10) / 50, "y" => $pos->y + 0.19, "z" => $pos->z + mt_rand(-10, 10) / 50, + "level" => $pos->level, //"speedX" => mt_rand(-3, 3) / 8, "speedY" => mt_rand(5, 8) / 2, //"speedZ" => mt_rand(-3, 3) / 8, @@ -170,4 +171,4 @@ class EntityAPI{ unset($entity); } } -} \ No newline at end of file +} diff --git a/src/API/LevelAPI.php b/src/API/LevelAPI.php index e2d143384..07726c77f 100644 --- a/src/API/LevelAPI.php +++ b/src/API/LevelAPI.php @@ -237,8 +237,7 @@ class LevelAPI{ } } - public function getAll() - { + public function getAll(){ return $this->levels; } diff --git a/src/API/PlayerAPI.php b/src/API/PlayerAPI.php index ed2e45d6a..b5ac7fae7 100644 --- a/src/API/PlayerAPI.php +++ b/src/API/PlayerAPI.php @@ -454,6 +454,7 @@ class PlayerAPI{ "z" => $this->server->spawn->z, ), "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)), "gamemode" => $this->server->gamemode, "health" => 20, diff --git a/src/API/ServerAPI.php b/src/API/ServerAPI.php index c909dd0e9..642600cc1 100644 --- a/src/API/ServerAPI.php +++ b/src/API/ServerAPI.php @@ -135,6 +135,7 @@ class ServerAPI{ $this->parseProperties(); define("DEBUG", $this->getProperty("debug", 1)); + define("ADVANCED_CACHE", $this->getProperty("enable-advanced-cache", false)); if($this->getProperty("port") !== false){ $this->setProperty("server-port", $this->getProperty("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] 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){ console("[INFO] [UPnP] Trying to port forward..."); UPnP_PortForward($this->getProperty("server-port")); @@ -290,7 +295,6 @@ class ServerAPI{ $this->server->gamemode = $this->getProperty("gamemode"); $this->server->difficulty = $this->getProperty("difficulty"); $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); } - public function setProperty($name, $value){ + public function setProperty($name, $value, $save = true){ $this->config->set($name, $value); - $this->writeProperties(); + if($save == true){ + $this->writeProperties(); + } $this->loadProperties(); } diff --git a/src/Player.php b/src/Player.php index 2eb21fd16..6eafacd6f 100644 --- a/src/Player.php +++ b/src/Player.php @@ -52,6 +52,7 @@ class Player{ public $spawned = false; public $inventory; public $slot; + public $hotbar; public $armor = array(); public $loggedIn = false; public $gamemode; @@ -111,6 +112,7 @@ class Player{ $this->gamemode = $this->server->gamemode; $this->level = $this->server->api->level->getDefault(); $this->slot = 0; + $this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1); $this->packetStats = array(0,0); $this->server->schedule(2, array($this, "handlePacketQueues"), 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("hotbar", $this->hotbar); $armor = array(); foreach($this->armor as $slot => $item){ @@ -887,7 +890,7 @@ class Player{ 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){ $this->entity->check = true; return false; @@ -1366,8 +1369,13 @@ class Player{ )); if(($this->gamemode & 0x01) === 0x01){ $this->slot = 0; + $this->hotbar = array(); + }elseif($this->data->exists("hotbar")){ + $this->hotbar = $this->data->get("hotbar"); + $this->slot = $this->hotbar[0]; }else{ $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->eid = $this->entity->eid; @@ -1487,7 +1495,6 @@ class Player{ if($this->spawned === false){ break; } - $data["eid"] = $this->eid; $data["player"] = $this; @@ -1527,8 +1534,15 @@ class Player{ $data["meta"] = $data["item"]->getMetadata(); if($this->server->handle("player.equipment.change", $data) !== false){ $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{ - $this->sendInventorySlot($data["slot"]); + //$this->sendInventorySlot($data["slot"]); + $this->sendInventory(); } if($this->entity->inAction === true){ $this->entity->inAction = false; @@ -1837,7 +1851,7 @@ class Player{ $this->entity->air = 300; $this->entity->setHealth(20, "respawn"); $this->entity->updateMetadata(); - } else { + }else{ break; } $this->sendInventory(); @@ -2198,10 +2212,16 @@ class Player{ if(($this->gamemode & 0x01) === CREATIVE){ return; } + $hotbar = array(); + foreach($this->hotbar as $slot){ + $hotbar[] = $slot <= -1 ? -1 : $slot + 9; + } + $this->dataPacket(MC_CONTAINER_SET_CONTENT, array( "windowid" => 0, "count" => count($this->inventory), "slots" => $this->inventory, + "hotbar" => $hotbar, )); } diff --git a/src/PocketMinecraftServer.php b/src/PocketMinecraftServer.php index 4fbddbf95..c6ffda609 100644 --- a/src/PocketMinecraftServer.php +++ b/src/PocketMinecraftServer.php @@ -36,7 +36,7 @@ class PocketMinecraftServer{ }*/ 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(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->startDatabase(); $this->api = false; @@ -65,7 +65,6 @@ class PocketMinecraftServer{ $this->tickMeasure = array_fill(0, 40, 0); $this->setType("normal"); $this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip); - $this->reloadConfig(); $this->stop = false; $this->ticks = 0; if(!defined("NO_THREADS")){ @@ -108,6 +107,7 @@ class PocketMinecraftServer{ } $this->schedule(20 * 15, array($this, "checkTicks"), 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); } @@ -156,10 +156,6 @@ class PocketMinecraftServer{ return $result; } - public function reloadConfig(){ - - } - public function debugInfo($console = false){ $info = array(); $info["tps"] = $this->getTPS(); @@ -372,46 +368,7 @@ class PocketMinecraftServer{ public function init(){ register_tick_function(array($this, "tick")); - console("[DEBUG] Starting internal ticker calculation", true, true, 2); - $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; - } - } + declare(ticks=5000); //Minimum TPS for main thread locks $this->loadEvents(); register_shutdown_function(array($this, "dumpError")); @@ -431,10 +388,32 @@ class PocketMinecraftServer{ if($this->stop === true){ 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"; $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){ @@ -465,7 +444,13 @@ class PocketMinecraftServer{ } $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"; ob_start(); phpinfo(); @@ -474,7 +459,7 @@ class PocketMinecraftServer{ $dump .= "\r\n```"; $name = "Error_Dump_".date("D_M_j-H.i.s-T_Y"); 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(){ @@ -594,6 +579,7 @@ class PocketMinecraftServer{ usleep(10000); } } + $this->tick(); } } @@ -643,11 +629,10 @@ class PocketMinecraftServer{ $this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT); $this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER); $this->preparedSQL->updateAction->execute(); - $schedule = $this->schedule[$cid]; - if(!is_callable($schedule[0])){ + if(!@is_callable($this->schedule[$cid][0])){ $return = false; }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){ diff --git a/src/build/compile.sh b/src/build/compile.sh index 3ec22f828..53b0c0542 100755 --- a/src/build/compile.sh +++ b/src/build/compile.sh @@ -1,12 +1,14 @@ #!/bin/bash -COMPILER_VERSION="0.14" +COMPILER_VERSION="0.15" PHP_VERSION="5.5.8" ZEND_VM="GOTO" LIBEDIT_VERSION="0.3" 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" 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" exit 1 fi -else +elif [ -z "$CFLAGS" ]; then if [ `getconf LONG_BIT` = "64" ]; then echo "[INFO] Compiling for current machine using 64-bit" CFLAGS="-m64 $CFLAGS" @@ -95,24 +97,22 @@ type $CC >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"$CC\ [ -z "$CFLAGS" ] && CFLAGS=""; [ -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 - $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 - export CFLAGS="-O3 -fno-gcse " + export CFLAGS="-O2 -fno-gcse " else - export CFLAGS="-O3 -fno-gcse $CFLAGS" + export CFLAGS="-O2 -fno-gcse $CFLAGS" fi else - export CFLAGS="-O3 -march=$march -mtune=$mtune -fno-gcse $CFLAGS" + export CFLAGS="-O2 -pipe -march=$march -mtune=$mtune -fno-gcse $CFLAGS" fi 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 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 cd install_data 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" 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]" set +e @@ -234,11 +256,12 @@ if [ "$1" == "crosscompile" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no" fi -./configure $OPTIMIZATION--prefix="$DIR/php5" \ ---exec-prefix="$DIR/php5" \ +./configure $OPTIMIZATION--prefix="$DIR/bin/php5" \ +--exec-prefix="$DIR/bin/php5" \ --with-curl="$HAVE_CURL" \ --with-zlib="$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 \ --disable-libxml \ --disable-xml \ @@ -263,6 +286,7 @@ $HAVE_LIBEDIT \ --enable-pthreads \ --enable-maintainer-zts \ --enable-zend-signals \ +--with-mysqli=mysqlnd \ --enable-embedded-mysqli \ --enable-bcmath \ --enable-cli \ @@ -280,8 +304,6 @@ echo " done!" cd "$DIR" echo -n "[INFO] Cleaning up..." 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 echo " done!" echo "[PocketMine] You should start the server now using \"./start.sh.\"" diff --git a/src/config.php b/src/config.php index f4f950f4c..ab3ebcdda 100644 --- a/src/config.php +++ b/src/config.php @@ -25,6 +25,8 @@ date_default_timezone_set("GMT"); if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){ $time = time(); $time -= $time % 60; + //TODO: Parse different time & date formats by region. ¬¬ world + //Example: USA exec("time.exe /T", $hour); $i = array_map("intval", explode(":", trim($hour[0]))); exec("date.exe /T", $date); @@ -37,10 +39,6 @@ if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){ $daylight = (int) date("I"); -if($daylight === 0){ - $offset -= 3600; -} - date_default_timezone_set(timezone_name_from_abbr("", $offset, $daylight)); gc_enable(); diff --git a/src/dependencies.php b/src/dependencies.php index c2c39f490..0da2459f6 100644 --- a/src/dependencies.php +++ b/src/dependencies.php @@ -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){ console("[ERROR] Unable to find the pthreads extension.", true, true, 0); ++$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){ @@ -66,13 +75,18 @@ if(!extension_loaded("sqlite3") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") ++$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){ console("[ERROR] Unable to find the Zlib extension.", true, true, 0); ++$errors; } 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 } diff --git a/src/functions.php b/src/functions.php index d61141eb5..9e2e2a528 100644 --- a/src/functions.php +++ b/src/functions.php @@ -192,6 +192,7 @@ function console($message, $EOL = true, $log = true, $level = 1){ if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){ switch($matches[1]){ case "ERROR": + case "SEVERE": $add .= FORMAT_RED; break; case "INTERNAL": diff --git a/src/lang/Installer/ko_KR.ini b/src/lang/Installer/ko_KR.ini index 4f8f9238e..9b5a62694 100644 --- a/src/lang/Installer/ko_KR.ini +++ b/src/lang/Installer/ko_KR.ini @@ -3,22 +3,22 @@ skip_installer=설치 마법사를 건너뛰겠습니까? welcome_to_pocketmine=PocketMine-MP에 오신 것을 환영합니다!\n서버 설치를 시작하기 전, 약관에 동의해야 합니다. \nPocketMine-MP는 GNU 약소 일반 공중 사용 허가서(LGPL) 하에 배포되고 있습니다. \n이 폴더에서 약관을 읽을 수 있습니다. 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=서버 설정을 시작합니다. -default_values_info=기본값을 수정하고 싶지 않으면, 엔터를 누르십시오. -server_properties=이 설정들은 server.properties 파일에서 세부적으로 변경할 수 있습니다. +default_values_info=기본값을 수정하고 싶지 않으면, 엔터를 누르십시기 바랍니다. +server_properties=이 설정들은 server.properties 파일에서 세부적으로 변경이 가능합니다. -name_your_server=당신의 서버 이름을 입력하십시오 -port_warning=만약 당신이 서버를 처음 설정한다면 포트 값을 변경하지 마십시오. +name_your_server=당신의 서버 이름을 입력하시기 바랍니다. +port_warning=만약 당신이 서버를 처음 설정한다면 포트 값을 변경하지 마세요. server_port=서버 포트 -invalid_port=서버 포트가 잘못 입력되었습니다 +invalid_port=서버 포트가 잘못 입력되었습니다. ram_warning=RAM 값은 PocketMine-MP에 할당할 메모리의 크기입니다. 128~256MB를 권장합니다. server_ram=서버 RAM (MB) -gamemode_info=크리에이티브 (1) 또는 서바이벌 (0) 게임모드 중 하나를 고르십시오 +gamemode_info=크리에이티브 (1) 또는 서바이벌 (0) 게임모드 중 하나를 고르세요. default_gamemode=기본 게임 모드 max_players=최대 동시 접속 인원 수 -spawn_protection_info=스폰 보호는 OP를 제외한 유저들이 스폰 지역 근처에서 블럭을 놓거나 부수는것을 방지합니다 +spawn_protection_info=스폰 보호는 OP를 제외한 유저들이 스폰 지역 근처에서 블럭을 놓거나 부수는것을 방지합니다. spawn_protection=스폰 지역 보호를 사용하겠습니까? op_info=OP는 서버 관리자를 뜻합니다. OP는 일반 플레이어보다 훨씬 많은 명령어들을 사용할 수 있습니다 diff --git a/src/lang/Installer/nl_NL.ini b/src/lang/Installer/nl_NL.ini index 5d515cc35..fb35e004b 100644 --- a/src/lang/Installer/nl_NL.ini +++ b/src/lang/Installer/nl_NL.ini @@ -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_warning=Je kunt later meerdere OP's toevoegen met het commando /op 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. 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. 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 diff --git a/src/lang/Installer/uk_UA.ini b/src/lang/Installer/uk_UA.ini new file mode 100644 index 000000000..6fb66a5e2 --- /dev/null +++ b/src/lang/Installer/uk_UA.ini @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/lang/Installer/zh_CN.ini b/src/lang/Installer/zh_CN.ini index 34962d203..4f04f81bf 100644 --- a/src/lang/Installer/zh_CN.ini +++ b/src/lang/Installer/zh_CN.ini @@ -26,7 +26,7 @@ op_who=OP的用户名是什么? op_warning=你可以执行\"/op <用户名>\"来添加OP. whitelist_info=白名单可以只允许在其列表内的玩家加入. whitelist_enable=您想启用白名单吗? -whitelist_warning=你可以用\"/whitelist add <用户名>\"把别人加入白名单. +whitelist_warning=你可以用"/whitelist add <用户名>"把别人加入白名单. query_warning1=请求是一个用于不同的程序的协议用来获取您服务器数据和登录的玩家. query_warning2=如果您禁止了它, 您将不能使用服务器列表. diff --git a/src/material/block/liquid/Lava.php b/src/material/block/liquid/Lava.php index 1f7fd557f..4e2c2266f 100644 --- a/src/material/block/liquid/Lava.php +++ b/src/material/block/liquid/Lava.php @@ -99,7 +99,7 @@ class LavaBlock extends LiquidBlock{ $b = $this->getSide($side); 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); ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL); } diff --git a/src/material/block/nonfull/Slab.php b/src/material/block/nonfull/Slab.php index d72ca7537..5773b7f6f 100644 --- a/src/material/block/nonfull/Slab.php +++ b/src/material/block/nonfull/Slab.php @@ -30,6 +30,7 @@ class SlabBlock extends TransparentBlock{ 4 => "Brick", 5 => "Stone Brick", 6 => "Quartz", + 7 => "", ); $this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab"; if(($this->meta & 0x08) === 0x08){ diff --git a/src/network/RCON.php b/src/network/RCON.php index 82190c696..c46ca8e5f 100644 --- a/src/network/RCON.php +++ b/src/network/RCON.php @@ -55,6 +55,8 @@ class RCON{ for($n = 0; $n < $this->threads; ++$n){ $this->workers[$n]->close(); $this->workers[$n]->join(); + usleep(50000); + $this->workers[$n]->kill(); } @socket_close($this->socket); $this->threads = 0; diff --git a/src/network/protocol/CustomPacketHandler.php b/src/network/protocol/CustomPacketHandler.php index b56d97759..9bd9d9678 100644 --- a/src/network/protocol/CustomPacketHandler.php +++ b/src/network/protocol/CustomPacketHandler.php @@ -800,12 +800,29 @@ class CustomPacketHandler{ for($s = 0; $s < $this->data["count"] and !$this->feof(); ++$s){ $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{ $this->raw .= chr($this->data["windowid"]); $this->raw .= Utils::writeShort(count($this->data["slots"])); foreach($this->data["slots"] as $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; case MC_CONTAINER_SET_DATA: diff --git a/src/pmf/Level.php b/src/pmf/Level.php index d5d6d0baf..8490acee9 100644 --- a/src/pmf/Level.php +++ b/src/pmf/Level.php @@ -467,14 +467,15 @@ class PMFLevel extends PMF{ ++$this->chunkChange[$index][$Y]; } $this->chunkChange[$index][-1] = true; - if($old_b instanceof LiquidBlock) - { + if($old_b instanceof LiquidBlock){ $pos = new Position($x, $y, $z, $this->level); - for($side = 0; $side <= 5; ++$side) - { + for($side = 0; $side <= 5; ++$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); } - else { ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL); } + if($b instanceof LavaBlock){ + 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; diff --git a/src/utils/Cache.php b/src/utils/Cache.php new file mode 100644 index 000000000..8d9a3e6d6 --- /dev/null +++ b/src/utils/Cache.php @@ -0,0 +1,53 @@ + $data){ + if($data[1] < $time){ + unset(self::$cached[$index]); + } + } + } + +} \ No newline at end of file diff --git a/src/utils/Config.php b/src/utils/Config.php index 4dce87927..ace15d218 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -86,6 +86,10 @@ class Config{ $this->load($this->file); $correct = $this->check(); } + + public function fixYAMLIndexes($str){ + return preg_replace("#^([ ]*)([a-zA-Z_]{1}[^\:]*)\:#m", "$1\"$2\":", $str); + } /** * @param string $file @@ -125,7 +129,8 @@ class Config{ $this->config = @json_decode($content, true); break; case CONFIG_YAML: - $this->config = Spyc::YAMLLoad($content); + $content = $this->fixYAMLIndexes($content); + $this->config = yaml_parse($content); break; case CONFIG_SERIALIZED: $this->config = @unserialize($content); @@ -172,7 +177,7 @@ class Config{ $content = json_encode($this->config, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING); break; case CONFIG_YAML: - $content = Spyc::YAMLDump($this->config); + $content = yaml_emit($this->config, YAML_UTF8_ENCODING); break; case CONFIG_SERIALIZED: $content = @serialize($this->config); @@ -256,13 +261,13 @@ class Config{ * @return boolean */ 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 $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 - else: + }else{ return isset($this->config[$k]); - endif; + } } /** diff --git a/src/utils/Java.php b/src/utils/Java.php index 88c8c1539..ba589fbfd 100644 --- a/src/utils/Java.php +++ b/src/utils/Java.php @@ -63,58 +63,4 @@ class Java_String{ } 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; - } - } \ No newline at end of file diff --git a/src/utils/Spyc.php b/src/utils/Spyc.php deleted file mode 100644 index e7d19d82f..000000000 --- a/src/utils/Spyc.php +++ /dev/null @@ -1,1038 +0,0 @@ - - * @author Chris Wanstrath - * @link http://code.google.com/p/spyc/ - * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package Spyc - */ - -if (!function_exists('spyc_load')) { - /** - * Parses YAML to array. - * @param string $string YAML string. - * @return array - */ - function spyc_load ($string) { - return Spyc::YAMLLoadString($string); - } -} - -if (!function_exists('spyc_load_file')) { - /** - * Parses YAML to array. - * @param string $file Path to YAML file. - * @return array - */ - function spyc_load_file ($file) { - return Spyc::YAMLLoad($file); - } -} - -/** - * The Simple PHP YAML Class. - * - * This class can be used to read a YAML file and convert its contents - * into a PHP array. It currently supports a very limited subsection of - * the YAML spec. - * - * Usage: - * - * $Spyc = new Spyc; - * $array = $Spyc->load($file); - * - * or: - * - * $array = Spyc::YAMLLoad($file); - * - * or: - * - * $array = spyc_load_file($file); - * - * @package Spyc - */ -class Spyc { - - // SETTINGS - - const REMPTY = "\0\0\0\0\0"; - - /** - * Setting this to true will force YAMLDump to enclose any string value in - * quotes. False by default. - * - * @var bool - */ - public $setting_dump_force_quotes = false; - - /** - * Setting this to true will forse YAMLLoad to use syck_load function when - * possible. False by default. - * @var bool - */ - public $setting_use_syck_is_possible = false; - - - - /**#@+ - * @access private - * @var mixed - */ - private $_dumpIndent; - private $_dumpWordWrap; - private $_containsGroupAnchor = false; - private $_containsGroupAlias = false; - private $path; - private $result; - private $LiteralPlaceHolder = '___YAML_Literal_Block___'; - private $SavedGroups = array(); - private $indent; - /** - * Path modifier that should be applied after adding current element. - * @var array - */ - private $delayedPath = array(); - - /**#@+ - * @access public - * @var mixed - */ - public $_nodeId; - -/** - * Load a valid YAML string to Spyc. - * @param string $input - * @return array - */ - public function load ($input) { - return $this->__loadString($input); - } - - /** - * Load a valid YAML file to Spyc. - * @param string $file - * @return array - */ - public function loadFile ($file) { - return $this->__load($file); - } - - /** - * Load YAML into a PHP array statically - * - * The load method, when supplied with a YAML stream (string or file), - * will do its best to convert YAML in a file into a PHP array. Pretty - * simple. - * Usage: - * - * $array = Spyc::YAMLLoad('lucky.yaml'); - * print_r($array); - * - * @access public - * @return array - * @param string $input Path of YAML file or string containing YAML - */ - public static function YAMLLoad($input) { - $Spyc = new Spyc; - return $Spyc->__load($input); - } - - /** - * Load a string of YAML into a PHP array statically - * - * The load method, when supplied with a YAML string, will do its best - * to convert YAML in a string into a PHP array. Pretty simple. - * - * Note: use this function if you don't want files from the file system - * loaded and processed as YAML. This is of interest to people concerned - * about security whose input is from a string. - * - * Usage: - * - * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); - * print_r($array); - * - * @access public - * @return array - * @param string $input String containing YAML - */ - public static function YAMLLoadString($input) { - $Spyc = new Spyc; - return $Spyc->__loadString($input); - } - - /** - * Dump YAML from PHP array statically - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as nothing.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public static function YAMLDump($array,$indent = false,$wordwrap = false) { - $spyc = new Spyc; - return $spyc->dump($array,$indent,$wordwrap); - } - - - /** - * Dump PHP array to YAML - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as tasteful.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public function dump($array,$indent = false,$wordwrap = false) { - // Dumps to some very clean YAML. We'll have to add some more features - // and options soon. And better support for folding. - - // New features and options. - if ($indent === false or !is_numeric($indent)) { - $this->_dumpIndent = 2; - } else { - $this->_dumpIndent = $indent; - } - - if ($wordwrap === false or !is_numeric($wordwrap)) { - $this->_dumpWordWrap = 40; - } else { - $this->_dumpWordWrap = $wordwrap; - } - - // New YAML document - $string = "---\n"; - - // Start at the base of the array and move through it. - if ($array) { - $array = (array)$array; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)){ $first_key = $key;} - $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); - $previous_key = $key; - } - } - return $string; - } - - /** - * Attempts to convert a key / value array item to YAML - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { - if (is_array($value)) { - if (empty ($value)){ - return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); - } - // It has children. What to do? - // Make it the right kind of item - $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); - // Add the indent - $indent += $this->_dumpIndent; - // Yamlize the array - $string .= $this->_yamlizeArray($value,$indent); - } elseif (!is_array($value)) { - // It doesn't have children. Yip. - $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); - } - return $string; - } - - /** - * Attempts to convert an array to YAML - * @access private - * @return string - * @param $array The array you want to convert - * @param $indent The indent of the current level - */ - private function _yamlizeArray($array,$indent) { - if (is_array($array)) { - $string = ''; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)){ $first_key = $key;} - $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); - $previous_key = $key; - } - return $string; - } else { - return false; - } - } - - /** - * Returns YAML from a key and a value - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { - // do some folding here, for blocks - if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false || strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || substr ($value, -1, 1) == ':')) { - $value = $this->_doLiteralBlock($value,$indent); - } else { - $value = $this->_doFolding($value,$indent); - } - - if ($value === array()){ $value = '[ ]';} - if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) { - $value = $this->_doLiteralBlock($value,$indent); - } - if (trim ($value) != $value){ - $value = $this->_doLiteralBlock($value,$indent); - } - - if (is_bool($value)) { - $value = ($value) ? "true" : "false"; - } - - if ($value === null){ $value = 'null';} - if ($value === "'" . self::REMPTY . "'"){ $value = null;} - - $spaces = str_repeat(' ',$indent); - - //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { - if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { - // It's a sequence - $string = $spaces.'- '.$value."\n"; - } else { - // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); - // It's mapped - if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } - $string = rtrim ($spaces.$key.': '.$value)."\n"; - } - return $string; - } - - /** - * Creates a literal block for dumping - * @access private - * @return string - * @param $value - * @param $indent int The value of the indent - */ - private function _doLiteralBlock($value,$indent) { - if ($value === "\n"){ return '\n';} - if (strpos($value, "\n") === false && strpos($value, "'") === false) { - return sprintf ("'%s'", $value); - } - if (strpos($value, "\n") === false && strpos($value, '"') === false) { - return sprintf ('"%s"', $value); - } - $exploded = explode("\n",$value); - $newValue = '|'; - $indent += $this->_dumpIndent; - $spaces = str_repeat(' ',$indent); - foreach ($exploded as $line) { - $newValue .= "\n" . $spaces . ($line); - } - return $newValue; - } - - /** - * Folds a string of text, if necessary - * @access private - * @return string - * @param $value The string you wish to fold - */ - private function _doFolding($value,$indent) { - // Don't do anything if wordwrap is set to 0 - - if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { - $indent += $this->_dumpIndent; - $indent = str_repeat(' ',$indent); - $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); - $value = ">\n".$indent.$wrapped; - } else { - if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY){ - $value = '"' . $value . '"'; - } - } - - - return $value; - } - -// LOADING FUNCTIONS - - private function __load($input) { - $Source = $this->loadFromSource($input); - return $this->loadWithSource($Source); - } - - private function __loadString($input) { - $Source = $this->loadFromString($input); - return $this->loadWithSource($Source); - } - - private function loadWithSource($Source) { - if (empty ($Source)){ return array();} - if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { - $array = syck_load (implode ('', $Source)); - return is_array($array) ? $array : array(); - } - - $this->path = array(); - $this->result = array(); - - $cnt = count($Source); - for ($i = 0; $i < $cnt; $i++) { - $line = $Source[$i]; - - $this->indent = strlen($line) - strlen(ltrim($line)); - $tempPath = $this->getParentPathByIndent($this->indent); - $line = self::stripIndent($line, $this->indent); - if (self::isComment($line)){ continue;} - if (self::isEmpty($line)){ continue;} - $this->path = $tempPath; - - $literalBlockStyle = self::startsLiteralBlock($line); - if ($literalBlockStyle) { - $line = rtrim ($line, $literalBlockStyle . " \n"); - $literalBlock = ''; - $line .= $this->LiteralPlaceHolder; - $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); - while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { - $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); - } - $i--; - } - - // Strip out comments - if (strpos ($line, '#')) { - $line = preg_replace('/\s*#([^"\']+)$/','',$line); - } - - while (++$i < $cnt && self::greedilyNeedNextLine($line)) { - $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); - } - $i--; - - $lineArray = $this->_parseLine($line); - - if ($literalBlockStyle){ - $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); - } - - $this->addArray($lineArray, $this->indent); - - foreach ($this->delayedPath as $indent => $delayedPath){ - $this->path[$indent] = $delayedPath; - } - $this->delayedPath = array(); - - } - return $this->result; - } - - private function loadFromSource ($input) { - if (!empty($input) && strpos($input, "\n") === false && file_exists($input)){ - return file($input); - } - - return $this->loadFromString($input); - } - - private function loadFromString ($input) { - $lines = explode("\n",$input); - foreach ($lines as $k => $_) { - $lines[$k] = rtrim ($_, "\r"); - } - return $lines; - } - - /** - * Parses YAML code and returns an array for a node - * @access private - * @return array - * @param string $line A line from the YAML file - */ - private function _parseLine($line) { - if (!$line){ return array();} - $line = trim($line); - if (!$line){ return array();} - - $array = array(); - - $group = $this->nodeContainsGroup($line); - if ($group) { - $this->addGroup($line, $group); - $line = $this->stripGroup ($line, $group); - } - - if ($this->startsMappedSequence($line)){ - return $this->returnMappedSequence($line); - } - if ($this->startsMappedValue($line)){ - return $this->returnMappedValue($line); - } - if ($this->isArrayElement($line)){ - return $this->returnArrayElement($line); - } - if ($this->isPlainArray($line)){ - return $this->returnPlainArray($line); - } - - return $this->returnKeyValuePair($line); - - } - - /** - * Finds the type of the passed value, returns the value as the new type. - * @access private - * @param string $value - * @return mixed - */ - private function _toType($value) { - if ($value === ''){ return null;} - $first_character = $value[0]; - $last_character = substr($value, -1, 1); - - $is_quoted = false; - do { - if (!$value){ break;} - if ($first_character != '"' && $first_character != "'"){ break;} - if ($last_character != '"' && $last_character != "'"){ break;} - $is_quoted = true; - } while (0); - - if ($is_quoted){ - return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); - } - if (strpos($value, ' #') !== false && !$is_quoted){ - $value = preg_replace('/\s+#(.+)$/','',$value); - } - if (!$is_quoted){ $value = str_replace('\n', "\n", $value);} - - if ($first_character == '[' && $last_character == ']') { - // Take out strings sequences and mappings - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === ''){ return array();} - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $value = array(); - foreach ($explode as $v) { - $value[] = $this->_toType($v); - } - return $value; - } - - if (strpos($value,': ')!==false && $first_character != '{') { - $array = explode(': ',$value); - $key = trim($array[0]); - array_shift($array); - $value = trim(implode(': ',$array)); - $value = $this->_toType($value); - return array($key => $value); - } - - if ($first_character == '{' && $last_character == '}') { - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === ''){ return array();} - // Inline Mapping - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $array = array(); - foreach ($explode as $v) { - $SubArr = $this->_toType($v); - if (empty($SubArr)){ continue;} - if (is_array ($SubArr)) { - $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; - } - $array[] = $SubArr; - } - return $array; - } - - if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { - return null; - } - - if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ - $intvalue = (int)$value; - if ($intvalue != PHP_INT_MAX){ - $value = $intvalue; - } - return $value; - } - - if (in_array($value, - array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { - return true; - } - - if (in_array(strtolower($value), - array('false', 'off', '-', 'no', 'n'))) { - return false; - } - - if (is_numeric($value)) { - if ($value === '0') {return 0;} - if (rtrim ($value, 0) === $value){ - $value = (float)$value; - } - return $value; - } - - return $value; - } - - /** - * Used in inlines to check for more inlines or quoted strings - * @access private - * @return array - */ - private function _inlineEscape($inline) { - // There's gotta be a cleaner way to do this... - // While pure sequences seem to be nesting just fine, - // pure mappings and mappings with sequences inside can't go very - // deep. This needs to be fixed. - - $seqs = array(); - $maps = array(); - $saved_strings = array(); - - // Check for strings - $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; - if (preg_match_all($regex,$inline,$strings)) { - $saved_strings = $strings[0]; - $inline = preg_replace($regex,'YAMLString',$inline); - } - unset($regex); - - $i = 0; - do { - - // Check for sequences - while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { - $seqs[] = $matchseqs[0]; - $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); - } - - // Check for mappings - while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { - $maps[] = $matchmaps[0]; - $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); - } - - if ($i++ >= 10){ break;} - - } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); - - $explode = explode(',',$inline); - $explode = array_map('trim', $explode); - $stringi = 0; $i = 0; - - while (1) { - - // Re-add the sequences - if (!empty($seqs)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - foreach ($seqs as $seqk => $seq) { - $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); - $value = $explode[$key]; - } - } - } - } - - // Re-add the mappings - if (!empty($maps)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLMap') !== false) { - foreach ($maps as $mapk => $map) { - $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); - $value = $explode[$key]; - } - } - } - } - - - // Re-add the strings - if (!empty($saved_strings)) { - foreach ($explode as $key => $value) { - while (strpos($value,'YAMLString') !== false) { - $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); - unset($saved_strings[$stringi]); - ++$stringi; - $value = $explode[$key]; - } - } - } - - $finished = true; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLMap') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLString') !== false) { - $finished = false; break; - } - } - if ($finished){ break;} - - $i++; - if ($i > 10) - break; // Prevent infinite loops. - } - - return $explode; - } - - private function literalBlockContinues ($line, $lineIndent) { - if (!trim($line)){ return true;} - if (strlen($line) - strlen(ltrim($line)) > $lineIndent){ return true;} - return false; - } - - private function referenceContentsByAlias ($alias) { - do { - if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } - $groupPath = $this->SavedGroups[$alias]; - $value = $this->result; - foreach ($groupPath as $k) { - $value = $value[$k]; - } - } while (false); - return $value; - } - - private function addArrayInline ($array, $indent) { - $CommonGroupPath = $this->path; - if (empty ($array)){ return false;} - - foreach ($array as $k => $_) { - $this->addArray(array($k => $_), $indent); - $this->path = $CommonGroupPath; - } - return true; - } - - private function addArray ($incoming_data, $incoming_indent) { - - // print_r ($incoming_data); - - if (count ($incoming_data) > 1){ - return $this->addArrayInline ($incoming_data, $incoming_indent); - } - $key = key ($incoming_data); - $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; - if ($key === '__!YAMLZero') {$key = '0';} - - if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. - if ($key || $key === '' || $key === '0') { - $this->result[$key] = $value; - } else { - $this->result[] = $value; end ($this->result); $key = key ($this->result); - } - $this->path[$incoming_indent] = $key; - return; - } - - - - $history = array(); - // Unfolding inner array tree. - $history[] = $_arr = $this->result; - foreach ($this->path as $k) { - $history[] = $_arr = $_arr[$k]; - } - - if ($this->_containsGroupAlias) { - $value = $this->referenceContentsByAlias($this->_containsGroupAlias); - $this->_containsGroupAlias = false; - } - - - // Adding string or numeric key to the innermost level or $this->arr. - if (is_string($key) && $key == '<<') { - if (!is_array ($_arr)) { $_arr = array (); } - - $_arr = array_merge ($_arr, $value); - } else if ($key || $key === '' || $key === '0') { - if (!is_array ($_arr)){ - $_arr = array ($key=>$value); - }else{ - $_arr[$key] = $value; - } - } else { - if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } - else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } - } - - $reverse_path = array_reverse($this->path); - $reverse_history = array_reverse ($history); - $reverse_history[0] = $_arr; - $cnt = count($reverse_history) - 1; - for ($i = 0; $i < $cnt; $i++) { - $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; - } - $this->result = $reverse_history[$cnt]; - - $this->path[$incoming_indent] = $key; - - if ($this->_containsGroupAnchor) { - $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; - if (is_array ($value)) { - $k = key ($value); - if (!is_int ($k)) { - $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; - } - } - $this->_containsGroupAnchor = false; - } - - } - - private static function startsLiteralBlock ($line) { - $lastChar = substr (trim($line), -1); - if ($lastChar != '>' && $lastChar != '|'){ return false;} - if ($lastChar == '|'){ return $lastChar;} - // HTML tags should not be counted as literal blocks. - if (preg_match ('#<.*?>$#', $line)){ return false;} - return $lastChar; - } - - private static function greedilyNeedNextLine($line) { - $line = trim ($line); - if (!strlen($line)){ return false;} - if (substr ($line, -1, 1) == ']'){ return false;} - if ($line[0] == '['){ return true;} - if (preg_match ('#^[^:]+?:\s*\[#', $line)){ return true;} - return false; - } - - private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { - $line = self::stripIndent($line, $indent); - if ($literalBlockStyle !== '|') { - $line = self::stripIndent($line); - } - $line = rtrim ($line, "\r\n\t ") . "\n"; - if ($literalBlockStyle == '|') { - return $literalBlock . $line; - } - if (strlen($line) == 0){ - return rtrim($literalBlock, ' ') . "\n"; - } - if ($line == "\n" && $literalBlockStyle == '>') { - return rtrim ($literalBlock, " \t") . "\n"; - } - if($line != "\n"){ - $line = trim ($line, "\r\n ") . " "; - } - return $literalBlock . $line; - } - - function revertLiteralPlaceHolder ($lineArray, $literalBlock) { - foreach ($lineArray as $k => $_) { - if (is_array($_)){ - $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); - }else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder){ - $lineArray[$k] = rtrim ($literalBlock, " \r\n"); - } - } - return $lineArray; - } - - private static function stripIndent ($line, $indent = -1) { - if ($indent == -1){ $indent = strlen($line) - strlen(ltrim($line));} - return substr ($line, $indent); - } - - private function getParentPathByIndent ($indent) { - if ($indent == 0){ return array();} - $linePath = $this->path; - do { - end($linePath); $lastIndentInParentPath = key($linePath); - if ($indent <= $lastIndentInParentPath){ array_pop ($linePath);} - } while ($indent <= $lastIndentInParentPath); - return $linePath; - } - - - private function clearBiggerPathValues ($indent) { - - - if ($indent == 0){ $this->path = array();} - if (empty ($this->path)){ return true;} - - foreach ($this->path as $k => $_) { - if ($k > $indent){ unset ($this->path[$k]);} - } - - return true; - } - - - private static function isComment ($line) { - if (!$line){ return false;} - if ($line[0] == '#'){ return true;} - if (trim($line, " \r\n\t") == '---'){ return true;} - return false; - } - - private static function isEmpty ($line) { - return (trim ($line) === ''); - } - - - private function isArrayElement ($line) { - if (!$line){ return false;} - if ($line[0] != '-'){ return false;} - if (strlen ($line) > 3){ - if (substr($line,0,3) == '---'){ return false;} - } - return true; - } - - private function isHashElement ($line) { - return strpos($line, ':'); - } - - private function isLiteral ($line) { - if ($this->isArrayElement($line)){ return false;} - if ($this->isHashElement($line)){ return false;} - return true; - } - - - private static function unquote ($value) { - if (!$value){ return $value;} - if (!is_string($value)){ return $value;} - if ($value[0] == '\''){ return trim ($value, '\'');} - if ($value[0] == '"'){ return trim ($value, '"');} - return $value; - } - - private function startsMappedSequence ($line) { - return ($line[0] == '-' && substr ($line, -1, 1) == ':'); - } - - private function returnMappedSequence ($line) { - $array = array(); - $key = self::unquote(trim(substr($line,1,-1))); - $array[$key] = array(); - $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); - return array($array); - } - - private function returnMappedValue ($line) { - $array = array(); - $key = self::unquote (trim(substr($line,0,-1))); - $array[$key] = ''; - return $array; - } - - private function startsMappedValue ($line) { - return (substr ($line, -1, 1) == ':'); - } - - private function isPlainArray ($line) { - return ($line[0] == '[' && substr ($line, -1, 1) == ']'); - } - - private function returnPlainArray ($line) { - return $this->_toType($line); - } - - private function returnKeyValuePair ($line) { - $array = array(); - $key = ''; - if (strpos ($line, ':')) { - // It's a key/value pair most likely - // If the key is in double quotes pull it out - if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { - $value = trim(str_replace($matches[1],'',$line)); - $key = $matches[2]; - } else { - // Do some guesswork as to the key and the value - $explode = explode(':',$line); - $key = trim($explode[0]); - array_shift($explode); - $value = trim(implode(':',$explode)); - } - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - if ($key === '0'){ $key = '__!YAMLZero';} - $array[$key] = $value; - } else { - $array = array ($line); - } - return $array; - - } - - - private function returnArrayElement ($line) { - if (strlen($line) <= 1){ return array(array());} // Weird %) - $array = array(); - $value = trim(substr($line,1)); - $value = $this->_toType($value); - $array[] = $value; - return $array; - } - - - private function nodeContainsGroup ($line) { - $symbolsForReference = 'A-z0-9_\-'; - if (strpos($line, '&') === false && strpos($line, '*') === false){ return false;} // Please die fast ;-) - if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)){ return $matches[1];} - if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)){ return $matches[1];} - if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)){ return $matches[1];} - if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)){ return $matches[1];} - if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)){ return $matches[1];} - return false; - - } - - private function addGroup ($line, $group) { - if ($group[0] == '&'){ $this->_containsGroupAnchor = substr ($group, 1);} - if ($group[0] == '*'){ $this->_containsGroupAlias = substr ($group, 1);} - //print_r ($this->path); - } - - private function stripGroup ($line, $group) { - $line = trim(str_replace($group, '', $line)); - return $line; - } -} \ No newline at end of file diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 3f08a5cca..62faeb2f8 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -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); } + 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){ if(Utils::$online === false){ return false; diff --git a/src/world/Entity.php b/src/world/Entity.php index 112b6026e..a550542db 100644 --- a/src/world/Entity.php +++ b/src/world/Entity.php @@ -144,6 +144,9 @@ class Entity extends Position{ } $this->updateLast(); $this->updatePosition(); + if($this->y < 0 and $this->class !== ENTITY_PLAYER){ + $this->close(); + } } public function updateFuse(){ @@ -598,7 +601,7 @@ class Entity extends Position{ public function getDirection(){ $rotation = ($this->yaw - 90) % 360; - if ($rotation < 0) { + if($rotation < 0) { $rotation += 360.0; } 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){ - 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->server->preparedSQL->entity->setLevel->reset(); $this->server->preparedSQL->entity->setLevel->clear(); diff --git a/src/world/Level.php b/src/world/Level.php index 99e1075b9..02099398f 100644 --- a/src/world/Level.php +++ b/src/world/Level.php @@ -299,6 +299,9 @@ class Level{ } $block->position($pos); $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])){ $this->changedBlocks[$i] = array(); $this->changedCount[$i] = 0; @@ -336,6 +339,9 @@ class Level{ $this->changedBlocks[$i] = array(); $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->changedCount[$i]; } @@ -365,6 +371,9 @@ class Level{ return false; } $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); } @@ -379,13 +388,22 @@ class Level{ if(!isset($this->level)){ 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){ if(!isset($this->level)){ 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(); for($Y = 0; $Y < 8; ++$Y){ if(($Yndex & (1 << $Y)) > 0){ @@ -401,6 +419,9 @@ class Level{ $ordered .= substr($mini, $j << 5, 24); //16 + 8 } } + if(ADVANCED_CACHE == true and $Yndex == 0xff){ + Cache::add($identifier, $ordered, 60); + } return $ordered; } @@ -434,7 +455,10 @@ class Level{ $z = (int) round($spawn->z); for(; $y > 0; --$y){ $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; } } diff --git a/src/world/Tile.php b/src/world/Tile.php index a59b63a95..d095850b1 100644 --- a/src/world/Tile.php +++ b/src/world/Tile.php @@ -234,7 +234,7 @@ class Tile extends Position{ $raw = $this->getSlot(0); $product = $this->getSlot(2); $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){ $this->lastUpdate = microtime(true); $this->data["MaxTime"] = $this->data["BurnTime"] = floor($fuel->getFuelTime() * 20); diff --git a/src/world/generator/object/tree/PineTreeObject.php b/src/world/generator/object/tree/PineTreeObject.php index ed3276aad..eb78dd985 100644 --- a/src/world/generator/object/tree/PineTreeObject.php +++ b/src/world/generator/object/tree/PineTreeObject.php @@ -64,17 +64,17 @@ class PineTreeObject extends TreeObject{ $firstMaxedRadius = false; for($leavesY = 0; $leavesY <= $leavesBottomY; ++$leavesY) { $yy = $this->totalHeight - $leavesY; - for ($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) { - for ($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) { - if (abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) { + for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) { + for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz) { + 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)); } } } - if ($leavesRadius >= $leavesMaxRadius) { + if($leavesRadius >= $leavesMaxRadius) { $leavesRadius = $firstMaxedRadius ? 1 : 0; $firstMaxedRadius = true; - if (++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius) { + if(++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius) { $leavesMaxRadius = $this->leavesAbsoluteMaxRadius; } }else{ diff --git a/src/world/generator/object/tree/SmallTreeObject.php b/src/world/generator/object/tree/SmallTreeObject.php index 394887e56..cd7b1610c 100644 --- a/src/world/generator/object/tree/SmallTreeObject.php +++ b/src/world/generator/object/tree/SmallTreeObject.php @@ -36,7 +36,7 @@ class SmallTreeObject extends TreeObject{ public function canPlaceObject(Level $level, Vector3 $pos, Random $random){ $radiusToCheck = 0; for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) { - if ($yy == 1 or $yy === $this->trunkHeight) { + if($yy == 1 or $yy === $this->trunkHeight) { ++$radiusToCheck; } for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ @@ -94,7 +94,7 @@ class SmallTreeObject extends TreeObject{ } // Place the trunk last - if( $leaflevel > 1 ) + if($leaflevel > 1) { $trunkpos = new Vector3( $pos->x, $pos->y + $yy, $pos->z ); $level->setBlockRaw($trunkpos, new WoodBlock( $this->type ) ); diff --git a/src/world/generator/object/tree/SpruceTreeObject.php b/src/world/generator/object/tree/SpruceTreeObject.php index c027ac644..e705764df 100644 --- a/src/world/generator/object/tree/SpruceTreeObject.php +++ b/src/world/generator/object/tree/SpruceTreeObject.php @@ -62,7 +62,7 @@ class SpruceTreeObject extends TreeObject{ for($yy = $this->totalHeight; $yy >= $this->leavesBottomY; --$yy){ for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx) { 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)); } } diff --git a/start.sh b/start.sh index 2e849db47..ae95e97a7 100755 --- a/start.sh +++ b/start.sh @@ -1,14 +1,9 @@ #!/bin/bash DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" cd "$DIR" -if [ -f ./php5/bin/php ]; then - mkdir -m 0777 bin/ - 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 $@ +if [ -f ./bin/php5/bin/php ]; then + exec ./bin/php5/bin/php -d enable_dl=On PocketMine-MP.php $@ else 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 \ No newline at end of file