mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 18:29:46 +00:00
Added Logger interface, threaded MainLogger and updated PluginLogger
This commit is contained in:
parent
9df56295f6
commit
7bd6f2ed91
@ -82,6 +82,7 @@ use pocketmine\tile\Sign;
|
||||
use pocketmine\tile\Spawnable;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
/**
|
||||
@ -392,7 +393,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->buffer->data = [];
|
||||
$this->tasks[] = $this->server->getScheduler()->scheduleRepeatingTask(new CallbackTask(array($this, "handlePacketQueues")), 1);
|
||||
$this->tasks[] = $this->server->getScheduler()->scheduleRepeatingTask(new CallbackTask(array($this, "clearQueue")), 20 * 60);
|
||||
console("[DEBUG] New Session started with " . $ip . ":" . $port . ". MTU " . $this->MTU . ", Client ID " . $this->clientID, true, true, 2);
|
||||
|
||||
$this->server->getLogger()->debug("New Session started with " . $ip . ":" . $port . ". MTU " . $this->MTU . ", Client ID " . $this->clientID);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1448,7 +1450,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->lastMeasure = microtime(true);
|
||||
$this->tasks[] = $this->server->getScheduler()->scheduleRepeatingTask(new CallbackTask(array($this, "measureLag")), 50);
|
||||
|
||||
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged in with entity id " . $this->id . " at (" . $this->getLevel()->getName() . ", " . round($this->x, 4) . ", " . round($this->y, 4) . ", " . round($this->z, 4) . ")");
|
||||
$this->server->getLogger()->info(TextFormat::AQUA . $this->username . TextFormat::WHITE . "[/" . $this->ip . ":" . $this->port . "] logged in with entity id " . $this->id . " at (" . $this->getLevel()->getName() . ", " . round($this->x, 4) . ", " . round($this->y, 4) . ", " . round($this->z, 4) . ")");
|
||||
|
||||
$this->server->getPluginManager()->callEvent(new PlayerJoinEvent($this, $this->username . " joined the game"));
|
||||
|
||||
@ -1517,7 +1519,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->teleport($this->lastCorrect, $this->entity->yaw, $this->entity->pitch, false);
|
||||
}
|
||||
if($this->blocked !== true){
|
||||
console("[WARNING] ".$this->username." moved too quickly!");
|
||||
$this->server->getLogger()->warning($this->username." moved too quickly!");
|
||||
}
|
||||
}else{*/
|
||||
$this->setPositionAndRotation($newPos, $packet->yaw, $packet->pitch);
|
||||
@ -2163,7 +2165,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console("[DEBUG] Unhandled " . $packet->pid() . " data packet for " . $this->username . " (" . $this->clientID . "): " . print_r($packet, true), true, true, 2);
|
||||
$this->server->getLogger()->debug("Unhandled " . $packet->pid() . " data packet for " . $this->username . " (" . $this->clientID . "): " . print_r($packet, true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2257,7 +2259,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||
$this->spawned = false;
|
||||
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
||||
$this->server->getLogger()->info(TextFormat::AQUA . $this->username . TextFormat::WHITE . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
||||
$this->windows = new \SplObjectStorage();
|
||||
$this->windowIndex = [];
|
||||
$this->chunksLoaded = [];
|
||||
|
@ -20,18 +20,6 @@
|
||||
*/
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Output text to the console, can contain Minecraft-formatted text.
|
||||
*
|
||||
* @param string $message
|
||||
* @param bool $EOL
|
||||
* @param bool $log
|
||||
* @param int $level
|
||||
*/
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
pocketmine\console($message, $EOL, $log, $level);
|
||||
}
|
||||
|
||||
function safe_var_dump(){
|
||||
static $cnt = 0;
|
||||
foreach(func_get_args() as $var){
|
||||
@ -78,6 +66,8 @@ namespace {
|
||||
|
||||
namespace pocketmine {
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\LogLevel;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
@ -154,11 +144,9 @@ namespace pocketmine {
|
||||
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? realpath($opts["plugins"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
|
||||
if((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])){
|
||||
define("pocketmine\\ANSI", true);
|
||||
}else{
|
||||
define("pocketmine\\ANSI", false);
|
||||
}
|
||||
define("pocketmine\\ANSI", ((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])));
|
||||
|
||||
$logger = new MainLogger(\pocketmine\PATH . "server.log", \pocketmine\ANSI);
|
||||
|
||||
function kill($pid){
|
||||
switch(Utils::getOS()){
|
||||
@ -172,57 +160,6 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output text to the console, can contain Minecraft-formatted text.
|
||||
*
|
||||
* @param $message
|
||||
* @param bool $EOL
|
||||
* @param bool $log
|
||||
* @param int $level
|
||||
*/
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
if(!defined("pocketmine\\DEBUG") or \pocketmine\DEBUG >= $level){
|
||||
$message .= $EOL === true ? PHP_EOL : "";
|
||||
if($message{0} !== "["){
|
||||
$message = "[INFO] $message";
|
||||
}
|
||||
$time = (\pocketmine\ANSI === true ? TextFormat::AQUA . date("H:i:s") . TextFormat::RESET : date("H:i:s")) . " ";
|
||||
$replaced = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message));
|
||||
if($log === true and (!defined("LOG") or LOG === true)){
|
||||
log(date("Y-m-d") . " " . $replaced, "server", false, $level);
|
||||
}
|
||||
if(\pocketmine\ANSI === true){
|
||||
$add = "";
|
||||
if(preg_match("/^\\[([a-zA-Z0-9]*)\\]/", $message, $matches) > 0){
|
||||
switch($matches[1]){
|
||||
case "ERROR":
|
||||
case "SEVERE":
|
||||
$add .= TextFormat::RED;
|
||||
break;
|
||||
case "TRACE":
|
||||
case "INTERNAL":
|
||||
case "DEBUG":
|
||||
$add .= TextFormat::GRAY;
|
||||
break;
|
||||
case "WARNING":
|
||||
$add .= TextFormat::YELLOW;
|
||||
break;
|
||||
case "NOTICE":
|
||||
$add .= TextFormat::AQUA;
|
||||
break;
|
||||
default:
|
||||
$add = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$message = TextFormat::toANSI($time . $add . $message . TextFormat::RESET);
|
||||
}else{
|
||||
$message = $replaced;
|
||||
}
|
||||
echo $message;
|
||||
}
|
||||
}
|
||||
|
||||
function getTrace($start = 1){
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
@ -262,11 +199,12 @@ namespace pocketmine {
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
);
|
||||
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? "ERROR" : "NOTICE";
|
||||
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? LogLevel::ERROR : LogLevel::NOTICE;
|
||||
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
|
||||
console("[$type] A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline", true, true, 0);
|
||||
$logger = MainLogger::getLogger();
|
||||
$logger->log($type, "A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
|
||||
foreach(getTrace() as $i => $line){
|
||||
console("[TRACE] $line");
|
||||
$logger->debug($line);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -296,22 +234,22 @@ namespace pocketmine {
|
||||
$errors = 0;
|
||||
|
||||
if(version_compare("5.4.0", PHP_VERSION) > 0){
|
||||
console("[ERROR] Use PHP >= 5.4.0", true, true, 0);
|
||||
$logger->critical("Use PHP >= 5.4.0");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sockets")){
|
||||
console("[ERROR] Unable to find the Socket extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the Socket extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("pthreads")){
|
||||
console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the pthreads extension.");
|
||||
++$errors;
|
||||
}else{
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
@ -319,52 +257,54 @@ namespace pocketmine {
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.4") < 0){
|
||||
console("[ERROR] pthreads >= 2.0.4 is required, while you have $pthreads_version.", true, true, 0);
|
||||
$logger->critical("pthreads >= 2.0.4 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("uopz")){
|
||||
//console("[NOTICE] Couldn't find the uopz extension. Some functions may be limited", true, true, 0);
|
||||
//$logger->notice("Couldn't find the uopz extension. Some functions may be limited");
|
||||
}
|
||||
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
console("[ERROR] You have the native PocketMine extension, but your version is lower than 0.0.1.", true, true, 0);
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
console("[ERROR] You have the native PocketMine extension, but your version is higher than 0.0.4.", true, true, 0);
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("Weakref") and !extension_loaded("weakref")){
|
||||
console("[ERROR] Unable to find the Weakref extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the Weakref extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("curl")){
|
||||
console("[ERROR] Unable to find the cURL extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the cURL extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sqlite3")){
|
||||
console("[ERROR] Unable to find the SQLite3 extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the SQLite3 extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("yaml")){
|
||||
console("[ERROR] Unable to find the YAML extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the YAML extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("zlib")){
|
||||
console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the Zlib extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
console("[ERROR] Please use the installer provided on the homepage, or recompile PHP again.", true, true, 0);
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
@ -383,11 +323,13 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
if(substr(__FILE__, 0, 7) !== "phar://"){
|
||||
console("[WARNING] Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
|
||||
$server = new Server($autoloader, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server = new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server->start();
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
kill(getmypid());
|
||||
exit(0);
|
||||
|
@ -84,6 +84,7 @@ use pocketmine\tile\Sign;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\Logger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
@ -122,6 +123,9 @@ class Server{
|
||||
/** @var TickScheduler */
|
||||
private $tickScheduler = null;
|
||||
|
||||
/** @var \pocketmine\utils\Logger */
|
||||
private $logger;
|
||||
|
||||
/** @var CommandReader */
|
||||
private $console = null;
|
||||
|
||||
@ -444,6 +448,13 @@ class Server{
|
||||
return $this->autoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger
|
||||
*/
|
||||
public function getLogger(){
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityMetadataStore
|
||||
*/
|
||||
@ -602,7 +613,7 @@ class Server{
|
||||
$nbt["SpawnX"] = (int) $data->get("spawn")["x"];
|
||||
$nbt["SpawnY"] = (int) $data->get("spawn")["y"];
|
||||
$nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
|
||||
console("[NOTICE] Old Player data found for \"" . $name . "\", upgrading profile");
|
||||
$this->logger->notice("Old Player data found for \"" . $name . "\", upgrading profile");
|
||||
foreach($data->get("inventory") as $slot => $item){
|
||||
if(count($item) === 3){
|
||||
$nbt->Inventory[$slot + 9] = new Compound(false, array(
|
||||
@ -641,7 +652,7 @@ class Server{
|
||||
}
|
||||
unlink($path . "$name.yml");
|
||||
}else{
|
||||
console("[NOTICE] Player data not found for \"" . $name . "\", creating new profile");
|
||||
$this->logger->notice("Player data not found for \"" . $name . "\", creating new profile");
|
||||
}
|
||||
$this->saveOfflinePlayerData($name, $nbt);
|
||||
|
||||
@ -809,13 +820,13 @@ class Server{
|
||||
if($this->isLevelLoaded($name)){
|
||||
return true;
|
||||
}elseif(!$this->isLevelGenerated($name)){
|
||||
console("[NOTICE] Level \"" . $name . "\" not found");
|
||||
$this->logger->notice("Level \"" . $name . "\" not found");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||
console("[INFO] Preparing level \"" . $name . "\"");
|
||||
$this->logger->info("Preparing level \"" . $name . "\"");
|
||||
$level = new LevelFormat($path . "level.pmf");
|
||||
if(!$level->isLoaded){
|
||||
console("[ERROR] Could not load level \"" . $name . "\"");
|
||||
@ -1175,14 +1186,16 @@ class Server{
|
||||
|
||||
/**
|
||||
* @param \SplClassLoader $autoloader
|
||||
* @param Logger $logger
|
||||
* @param string $filePath
|
||||
* @param string $dataPath
|
||||
* @param string $pluginPath
|
||||
*/
|
||||
public function __construct(\SplClassLoader $autoloader, $filePath, $dataPath, $pluginPath){
|
||||
public function __construct(\SplClassLoader $autoloader, Logger $logger, $filePath, $dataPath, $pluginPath){
|
||||
self::$instance = $this;
|
||||
|
||||
$this->autoloader = $autoloader;
|
||||
$this->logger = $logger;
|
||||
$this->filePath = $filePath;
|
||||
$this->dataPath = $dataPath;
|
||||
$this->pluginPath = $pluginPath;
|
||||
@ -1211,9 +1224,9 @@ class Server{
|
||||
$this->console = new CommandReader();
|
||||
|
||||
$version = new VersionString($this->getPocketMineVersion());
|
||||
console("[INFO] Starting Minecraft: PE server version " . TextFormat::AQUA . $this->getVersion());
|
||||
$this->logger->info("Starting Minecraft: PE server version " . TextFormat::AQUA . $this->getVersion());
|
||||
|
||||
console("[INFO] Loading properties...");
|
||||
$this->logger->info("Loading properties...");
|
||||
$this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, array(
|
||||
"motd" => "Minecraft: PE Server",
|
||||
"server-port" => 19132,
|
||||
@ -1250,7 +1263,7 @@ class Server{
|
||||
$value = array("M" => 1, "G" => 1024);
|
||||
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
|
||||
if($real < 128){
|
||||
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
|
||||
$this->logger->warning("PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
|
||||
}
|
||||
@ini_set("memory_limit", $memory);
|
||||
}else{
|
||||
@ -1265,20 +1278,20 @@ class Server{
|
||||
define("ADVANCED_CACHE", $this->getConfigBoolean("enable-advanced-cache", false));
|
||||
define("MAX_CHUNK_RATE", 20 / $this->getConfigInt("max-chunks-per-second", 7)); //Default rate ~448 kB/s
|
||||
if(ADVANCED_CACHE == true){
|
||||
console("[INFO] Advanced cache enabled");
|
||||
$this->logger->info("Advanced cache enabled");
|
||||
}
|
||||
|
||||
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and function_exists("cli_set_process_title")){
|
||||
@cli_set_process_title("PocketMine-MP " . $this->getPocketMineVersion());
|
||||
}
|
||||
|
||||
console("[INFO] Starting Minecraft PE server on " . ($this->getIp() === "" ? "*" : $this->getIp()) . ":" . $this->getPort());
|
||||
$this->logger->info("Starting Minecraft PE server on " . ($this->getIp() === "" ? "*" : $this->getIp()) . ":" . $this->getPort());
|
||||
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
|
||||
$this->serverID = Binary::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 0, 8));
|
||||
$this->interface = new ThreadedHandler("255.255.255.255", $this->getPort(), $this->getIp() === "" ? "0.0.0.0" : $this->getIp());
|
||||
|
||||
console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0);
|
||||
console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0);
|
||||
$this->logger->info("This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0);
|
||||
$this->logger->info("PocketMine-MP is distributed under the LGPL License", true, true, 0);
|
||||
|
||||
$this->consoleSender = new ConsoleCommandSender();
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
@ -1331,8 +1344,8 @@ class Server{
|
||||
/*
|
||||
//TODO
|
||||
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
|
||||
console("[INFO] Checking for new server version");
|
||||
console("[INFO] Last check: " . TextFormat::AQUA . date("Y-m-d H:i:s", $this->getProperty("last-update")) . "\x1b[0m");
|
||||
$this->logger->info("Checking for new server version");
|
||||
$this->logger->info("Last check: " . TextFormat::AQUA . date("Y-m-d H:i:s", $this->getProperty("last-update")));
|
||||
if($this->server->version->isDev()){
|
||||
$info = json_decode(Utils::getURL("https://api.github.com/repos/PocketMine/PocketMine-MP/commits"), true);
|
||||
if($info === false or !isset($info[0])){
|
||||
@ -1341,13 +1354,13 @@ class Server{
|
||||
$last = new \DateTime($info[0]["commit"]["committer"]["date"]);
|
||||
$last = $last->getTimestamp();
|
||||
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and \pocketmine\GIT_COMMIT != $info[0]["sha"]){
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "A new DEVELOPMENT version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "Commit \"" . $info[0]["commit"]["message"] . "\" [" . substr($info[0]["sha"], 0, 10) . "] by " . $info[0]["commit"]["committer"]["name"]);
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/" . $info[0]["sha"] . ".zip");
|
||||
console("[NOTICE] This message will disappear after issuing the command \"/update-done\"");
|
||||
$this->logger->notice("" . TextFormat::YELLOW . "A new DEVELOPMENT version of PocketMine-MP has been released!");
|
||||
$this->logger->notice("" . TextFormat::YELLOW . "Commit \"" . $info[0]["commit"]["message"] . "\" [" . substr($info[0]["sha"], 0, 10) . "] by " . $info[0]["commit"]["committer"]["name"]);
|
||||
$this->logger->notice("" . TextFormat::YELLOW . "Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/" . $info[0]["sha"] . ".zip");
|
||||
$this->logger->notice("This message will disappear after issuing the command \"/update-done\"");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] " . TextFormat::AQUA . "This is the latest DEVELOPMENT version");
|
||||
$this->logger->info("" . TextFormat::AQUA . "This is the latest DEVELOPMENT version");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@ -1360,13 +1373,13 @@ class Server{
|
||||
$update = new VersionString($info[0]["name"]);
|
||||
$updateN = $update->getNumber();
|
||||
if($updateN > $newestN){
|
||||
console("[NOTICE] " . TextFormat::GREEN . "A new STABLE version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] " . TextFormat::GREEN . "Version \"" . $info[0]["name"] . "\" #" . $updateN);
|
||||
console("[NOTICE] Get it at PocketMine.net or at " . $info[0]["zipball_url"]);
|
||||
console("[NOTICE] This message will disappear as soon as you update");
|
||||
$this->logger->notice("" . TextFormat::GREEN . "A new STABLE version of PocketMine-MP has been released!");
|
||||
$this->logger->notice("" . TextFormat::GREEN . "Version \"" . $info[0]["name"] . "\" #" . $updateN);
|
||||
$this->logger->notice("Get it at PocketMine.net or at " . $info[0]["zipball_url"]);
|
||||
$this->logger->notice("This message will disappear as soon as you update");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] " . TextFormat::AQUA . "This is the latest STABLE version");
|
||||
$this->logger->info("" . TextFormat::AQUA . "This is the latest STABLE version");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1475,7 +1488,7 @@ class Server{
|
||||
}
|
||||
|
||||
public function reload(){
|
||||
console("[INFO] Saving levels...");
|
||||
$this->logger->info("Saving levels...");
|
||||
|
||||
foreach($this->levels as $level){
|
||||
$level->save();
|
||||
@ -1485,7 +1498,7 @@ class Server{
|
||||
$this->pluginManager->clearPlugins();
|
||||
$this->commandMap->clearCommands();
|
||||
|
||||
console("[INFO] Reloading properties...");
|
||||
$this->logger->info("Reloading properties...");
|
||||
$this->properties->reload();
|
||||
$this->maxPlayers = $this->getConfigInt("max-players", 20);
|
||||
|
||||
@ -1493,7 +1506,7 @@ class Server{
|
||||
$value = array("M" => 1, "G" => 1024);
|
||||
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
|
||||
if($real < 128){
|
||||
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
|
||||
$this->logger->warning("PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
|
||||
}
|
||||
@ini_set("memory_limit", $memory);
|
||||
}else{
|
||||
@ -1530,7 +1543,7 @@ class Server{
|
||||
}
|
||||
|
||||
if($this->getConfigBoolean("upnp-forwarding", false) === true){
|
||||
console("[INFO] [UPnP] Removing port forward...");
|
||||
$this->logger->info("[UPnP] Removing port forward...");
|
||||
UPnP::RemovePortForward($this->getPort());
|
||||
}
|
||||
|
||||
@ -1571,7 +1584,7 @@ class Server{
|
||||
|
||||
|
||||
if($this->getConfigBoolean("upnp-forwarding", false) == true){
|
||||
console("[INFO] [UPnP] Trying to port forward...");
|
||||
$this->logger->info("[UPnP] Trying to port forward...");
|
||||
UPnP::PortForward($this->getPort());
|
||||
}
|
||||
|
||||
@ -1585,9 +1598,9 @@ class Server{
|
||||
pcntl_signal(SIGHUP, array($this, "shutdown"));
|
||||
}
|
||||
|
||||
console("[INFO] Default game type: " . self::getGamemodeString($this->getGamemode())); //TODO: string name
|
||||
$this->logger->info("Default game type: " . self::getGamemodeString($this->getGamemode())); //TODO: string name
|
||||
|
||||
console('[INFO] Done (' . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
|
||||
$this->logger->info("Done (" . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
|
||||
if(Utils::getOS() === "win"){ //Workaround less usleep() waste
|
||||
$this->tickProcessorWindows();
|
||||
}else{
|
||||
@ -1619,7 +1632,7 @@ class Server{
|
||||
|
||||
public function checkTicks(){
|
||||
if($this->getTicksPerSecond() < 12){
|
||||
console("[WARNING] Can't keep up! Is the server overloaded?");
|
||||
$this->logger->warning("Can't keep up! Is the server overloaded?");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1639,7 +1652,7 @@ class Server{
|
||||
return;
|
||||
}
|
||||
ini_set("memory_limit", "-1"); //Fix error dump not dumped on memory problems
|
||||
console("[SEVERE] An unrecoverable has occurred and the server has crashed. Creating an error dump");
|
||||
$this->logger->emergency("An unrecoverable has occurred 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(
|
||||
@ -1715,7 +1728,7 @@ class Server{
|
||||
$dump .= "\r\n```";
|
||||
$name = "Error_Dump_" . date("D_M_j-H.i.s-T_Y");
|
||||
log($dump, $name, true, 0, true);
|
||||
console("[SEVERE] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
|
||||
$this->logger->emergency("Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
|
||||
}
|
||||
|
||||
private function tickProcessor(){
|
||||
@ -1764,7 +1777,7 @@ class Server{
|
||||
break;
|
||||
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
|
||||
if($packet->structure !== RakNetInfo::STRUCTURE){
|
||||
console("[DEBUG] Incorrect structure #" . $packet->structure . " from " . $packet->ip . ":" . $packet->port, true, true, 2);
|
||||
$this->logger->debug("Incorrect structure #" . $packet->structure . " from " . $packet->ip . ":" . $packet->port);
|
||||
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->ip = $packet->ip;
|
||||
|
@ -25,6 +25,7 @@ use pocketmine\permission\PermissibleBase;
|
||||
use pocketmine\permission\PermissionAttachment;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class ConsoleCommandSender implements CommandSender{
|
||||
|
||||
@ -102,8 +103,7 @@ class ConsoleCommandSender implements CommandSender{
|
||||
*/
|
||||
public function sendMessage($message){
|
||||
foreach(explode("\n", trim($message)) as $line){
|
||||
$line = trim($line);
|
||||
console($line);
|
||||
MainLogger::getLogger()->info($line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ class Level{
|
||||
if($this === $this->server->getDefaultLevel() and $force !== true){
|
||||
return false;
|
||||
}
|
||||
console("[INFO] Unloading level \"" . $this->getName() . "\"");
|
||||
$this->server->getLogger()->info("Unloading level \"" . $this->getName() . "\"");
|
||||
$this->nextSave = PHP_INT_MAX;
|
||||
$this->save();
|
||||
$defaultLevel = $this->server->getDefaultLevel();
|
||||
|
@ -25,6 +25,7 @@ use pocketmine\level\format\pmf\LevelFormat;
|
||||
use pocketmine\level\format\PocketChunkParser;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class LevelImport{
|
||||
private $path;
|
||||
@ -36,7 +37,7 @@ class LevelImport{
|
||||
public function import(){
|
||||
if(file_exists($this->path . "tileEntities.dat")){ //OldPM
|
||||
$level = unserialize(file_get_contents($this->path . "level.dat"));
|
||||
console("[INFO] Importing OldPM level \"" . $level["LevelName"] . "\" to PMF format");
|
||||
MainLogger::getLogger()->info("Importing OldPM level \"" . $level["LevelName"] . "\" to PMF format");
|
||||
$entities = new Config($this->path . "entities.yml", Config::YAML, unserialize(file_get_contents($this->path . "entities.dat")));
|
||||
$entities->save();
|
||||
$tiles = new Config($this->path . "tiles.yml", Config::YAML, unserialize(file_get_contents($this->path . "tileEntities.dat")));
|
||||
@ -48,7 +49,7 @@ class LevelImport{
|
||||
if($level["LevelName"] == ""){
|
||||
$level["LevelName"] = "world" . time();
|
||||
}
|
||||
console("[INFO] Importing Pocket level \"" . $level->LevelName . "\" to PMF format");
|
||||
MainLogger::getLogger()->info("Importing Pocket level \"" . $level->LevelName . "\" to PMF format");
|
||||
unset($level->Player);
|
||||
$nbt->read(substr(file_get_contents($this->path . "entities.dat"), 12));
|
||||
$entities = $nbt->getData();
|
||||
@ -111,7 +112,7 @@ class LevelImport{
|
||||
$pmf->setPopulated($X, $Z);
|
||||
$pmf->saveChunk($X, $Z);
|
||||
}
|
||||
console("[NOTICE] Importing level " . ceil(($Z + 1) / 0.16) . "%");
|
||||
MainLogger::getLogger()->notice("Importing level " . ceil(($Z + 1) / 0.16) . "%");
|
||||
}
|
||||
$chunks->map = null;
|
||||
$chunks = null;
|
||||
|
@ -41,7 +41,6 @@ class PocketChunkParser{
|
||||
|
||||
private function loadLocationTable(){
|
||||
$this->location = [];
|
||||
console("[DEBUG] Loading Chunk Location table...", true, true, 2);
|
||||
for($offset = 0; $offset < 0x1000; $offset += 4){
|
||||
$data = Binary::readLInt(substr($this->raw, $offset, 4));
|
||||
$sectors = $data & 0xff;
|
||||
@ -136,7 +135,6 @@ class PocketChunkParser{
|
||||
return false;
|
||||
}
|
||||
$this->loadLocationTable();
|
||||
console("[DEBUG] Loading chunks...", true, true, 2);
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
$this->map[$x] = [];
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
@ -144,13 +142,11 @@ class PocketChunkParser{
|
||||
}
|
||||
}
|
||||
$this->raw = "";
|
||||
console("[DEBUG] Chunks loaded!", true, true, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveMap($final = false){
|
||||
console("[DEBUG] Saving chunks...", true, true, 2);
|
||||
|
||||
$fp = fopen($this->file, "r+b");
|
||||
flock($fp, LOCK_EX);
|
||||
@ -165,7 +161,6 @@ class PocketChunkParser{
|
||||
$original = filesize($this->file);
|
||||
file_put_contents($this->file . ".gz", gzdeflate(gzdeflate(file_get_contents($this->file), 9), 9)); //Double compression for flat maps
|
||||
$compressed = filesize($this->file . ".gz");
|
||||
console("[DEBUG] Saved chunks.dat.gz with " . round(($compressed / $original) * 100, 2) . "% (" . round($compressed / 1024, 2) . "KB) of the original size", true, true, 2);
|
||||
if($final === true){
|
||||
@unlink($this->file);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class LevelFormat extends PMF{
|
||||
const VERSION = 2;
|
||||
@ -121,7 +122,7 @@ class LevelFormat extends PMF{
|
||||
$this->seek(5);
|
||||
$this->levelData["version"] = ord($this->read(1));
|
||||
if($this->levelData["version"] > self::VERSION){
|
||||
console("[ERROR] New unsupported PMF Level format version #" . $this->levelData["version"] . ", current version is #" . self::VERSION);
|
||||
MainLogger::getLogger()->error("New unsupported PMF Level format version #" . $this->levelData["version"] . ", current version is #" . self::VERSION);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -161,7 +162,7 @@ class LevelFormat extends PMF{
|
||||
}
|
||||
|
||||
private function upgrade_From0_To1(){
|
||||
console("[NOTICE] Old PMF Level format version #0 detected, upgrading to version #1");
|
||||
MainLogger::getLogger()->notice("Old PMF Level format version #0 detected, upgrading to version #1");
|
||||
for($index = 0; $index < 256; ++$index){
|
||||
$X = $index & 0x0F;
|
||||
$Z = $index >> 4;
|
||||
@ -186,7 +187,7 @@ class LevelFormat extends PMF{
|
||||
}
|
||||
|
||||
private function upgrade_From1_To2(){
|
||||
console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2");
|
||||
MainLogger::getLogger()->notice("Old PMF Level format version #1 detected, upgrading to version #2");
|
||||
$nbt = new Compound("", array(
|
||||
new Enum("Entities", []),
|
||||
new Enum("TileEntities", [])
|
||||
@ -308,7 +309,7 @@ class LevelFormat extends PMF{
|
||||
if(($this->chunkInfo[$index][0] & (1 << $Y)) !== 0){
|
||||
// 4096 + 2048 + 2048, Block Data, Meta, Light
|
||||
if(strlen($this->chunks[$index][$Y] = substr($chunk, $offset, 8192)) < 8192){
|
||||
console("[NOTICE] Empty corrupt chunk detected [$X,$Z,:$Y], recovering contents", true, true, 2);
|
||||
MainLogger::getLogger()->notice("Empty corrupt chunk detected [$X,$Z,:$Y], recovering contents");
|
||||
$this->fillMiniChunk($X, $Z, $Y);
|
||||
}
|
||||
$offset += 8192;
|
||||
|
@ -25,6 +25,8 @@
|
||||
namespace pocketmine\level\format\pmf;
|
||||
|
||||
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class PMF{
|
||||
const VERSION = 0x01;
|
||||
|
||||
@ -78,7 +80,7 @@ class PMF{
|
||||
$this->type = ord($this->read(1));
|
||||
break;
|
||||
default:
|
||||
console("[ERROR] Tried loading non-supported PMF version " . $this->version . " on file " . $this->file);
|
||||
MainLogger::getLogger()->alert("Tried loading non-supported PMF version " . $this->version . " on file " . $this->file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace pocketmine\network;
|
||||
use pocketmine\network\query\QueryPacket;
|
||||
use pocketmine\network\raknet\Info;
|
||||
use pocketmine\network\raknet\Packet as RakNetPacket;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class ThreadedHandler extends \Thread{
|
||||
protected $bandwidthUp;
|
||||
@ -124,8 +125,8 @@ class ThreadedHandler extends \Thread{
|
||||
@socket_set_option($this->socket, SOL_SOCKET, SO_SNDBUF, 1024 * 1024 * 2); //2MB
|
||||
@socket_set_option($this->socket, SOL_SOCKET, SO_RCVBUF, 1024 * 1024); //1MB
|
||||
}else{
|
||||
console("[SEVERE] **** FAILED TO BIND TO " . $this->serverip . ":" . $this->port . "!", true, true, 0);
|
||||
console("[SEVERE] Perhaps a server is already running on that port?", true, true, 0);
|
||||
MainLogger::getLogger()->critical("**** FAILED TO BIND TO " . $this->serverip . ":" . $this->port . "!", true, true, 0);
|
||||
MainLogger::getLogger()->critical("Perhaps a server is already running on that port?", true, true, 0);
|
||||
exit(1);
|
||||
}
|
||||
socket_set_nonblock($this->socket);
|
||||
|
@ -33,11 +33,11 @@ class QueryHandler{
|
||||
private $socket, $server, $lastToken, $token, $longData, $timeout;
|
||||
|
||||
public function __construct(){
|
||||
console("[INFO] Starting GS4 status listener");
|
||||
$this->server = Server::getInstance();
|
||||
$this->server->getLogger()->info("Starting GS4 status listener");
|
||||
$addr = ($ip = $this->server->getIp()) != "" ? $ip : "0.0.0.0";
|
||||
$port = $this->server->getPort();
|
||||
console("[INFO] Setting query port to $port");
|
||||
$this->server->getLogger()->info("Setting query port to $port");
|
||||
/*
|
||||
The Query protocol is built on top of the existing Minecraft PE UDP network stack.
|
||||
Because the 0xFE packet does not exist in the MCPE protocol,
|
||||
@ -50,7 +50,7 @@ class QueryHandler{
|
||||
$this->regenerateToken();
|
||||
$this->lastToken = $this->token;
|
||||
$this->regenerateInfo();
|
||||
console("[INFO] Query running on $addr:$port");
|
||||
$this->server->getLogger()->info("Query running on $addr:$port");
|
||||
}
|
||||
|
||||
public function regenerateInfo(){
|
||||
|
@ -28,6 +28,7 @@ namespace pocketmine\network\rcon;
|
||||
use pocketmine\command\RemoteConsoleCommandSender;
|
||||
use pocketmine\scheduler\CallbackTask;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
||||
@ -43,9 +44,9 @@ class RCON{
|
||||
public function __construct($password, $port = 19132, $interface = "0.0.0.0", $threads = 1, $clientsPerThread = 50){
|
||||
$this->workers = [];
|
||||
$this->password = (string) $password;
|
||||
console("[INFO] Starting remote control listener");
|
||||
MainLogger::getLogger()->info("Starting remote control listener");
|
||||
if($this->password === ""){
|
||||
console("[ERROR] RCON can't be started: Empty password");
|
||||
MainLogger::getLogger()->critical("RCON can't be started: Empty password");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -53,7 +54,7 @@ class RCON{
|
||||
$this->clientsPerThread = (int) max(1, $clientsPerThread);
|
||||
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if($this->socket === false or !socket_bind($this->socket, $interface, (int) $port) or !socket_listen($this->socket)){
|
||||
console("[ERROR] RCON can't be started: " . socket_strerror(socket_last_error()));
|
||||
MainLogger::getLogger()->critical("RCON can't be started: " . socket_strerror(socket_last_error()));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -63,7 +64,7 @@ class RCON{
|
||||
$this->workers[$n] = new RCONInstance($this->socket, $this->password, $this->clientsPerThread);
|
||||
}
|
||||
@socket_getsockname($this->socket, $addr, $port);
|
||||
console("[INFO] RCON running on $addr:$port");
|
||||
MainLogger::getLogger()->info("RCON running on $addr:$port");
|
||||
Server::getInstance()->getScheduler()->scheduleRepeatingTask(new CallbackTask(array($this, "check")), 3);
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ class RCON{
|
||||
$this->workers[$n] = new RCONInstance($this->socket, $this->password, $this->clientsPerThread);
|
||||
}elseif($this->workers[$n]->isWaiting()){
|
||||
if($this->workers[$n]->response !== ""){
|
||||
console($this->workers[$n]->response);
|
||||
MainLogger::getLogger()->info($this->workers[$n]->response);
|
||||
$this->workers[$n]->notify();
|
||||
}else{
|
||||
Server::getInstance()->dispatchCommand($response = new RemoteConsoleCommandSender(), $this->workers[$n]->cmd);
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\permission;
|
||||
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class BanList{
|
||||
|
||||
@ -141,7 +142,7 @@ class BanList{
|
||||
}
|
||||
fclose($fp);
|
||||
}else{
|
||||
console("[ERROR] Could not load ban list");
|
||||
MainLogger::getLogger()->error("Could not load ban list");
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ class BanList{
|
||||
}
|
||||
fclose($fp);
|
||||
}else{
|
||||
console("[ERROR] Could not save ban list");
|
||||
MainLogger::getLogger()->error("Could not save ban list");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ namespace pocketmine\plugin;
|
||||
use pocketmine\event\plugin\PluginDisableEvent;
|
||||
use pocketmine\event\plugin\PluginEnableEvent;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
/**
|
||||
* Handles different types of plugins
|
||||
@ -51,7 +52,7 @@ class PharPluginLoader implements PluginLoader{
|
||||
*/
|
||||
public function loadPlugin($file){
|
||||
if(\Phar::isValidPharFilename($file) and ($description = $this->getPluginDescription($file)) instanceof PluginDescription){
|
||||
console("[INFO] Loading " . $description->getFullName());
|
||||
MainLogger::getLogger()->info("Loading " . $description->getFullName());
|
||||
$dataFolder = dirname($file) . DIRECTORY_SEPARATOR . $description->getName();
|
||||
if(file_exists($dataFolder) and !is_dir($dataFolder)){
|
||||
throw new \Exception("Projected dataFolder '" . $dataFolder . "' for " . $description->getName() . " exists and is not a directory");
|
||||
@ -121,7 +122,7 @@ class PharPluginLoader implements PluginLoader{
|
||||
*/
|
||||
public function enablePlugin(Plugin $plugin){
|
||||
if($plugin instanceof PluginBase and !$plugin->isEnabled()){
|
||||
console("[INFO] Enabling " . $plugin->getDescription()->getFullName());
|
||||
MainLogger::getLogger()->info("Enabling " . $plugin->getDescription()->getFullName());
|
||||
|
||||
$plugin->setEnabled(true);
|
||||
|
||||
@ -134,7 +135,7 @@ class PharPluginLoader implements PluginLoader{
|
||||
*/
|
||||
public function disablePlugin(Plugin $plugin){
|
||||
if($plugin instanceof PluginBase and $plugin->isEnabled()){
|
||||
console("[INFO] Disabling " . $plugin->getDescription()->getFullName());
|
||||
MainLogger::getLogger()->info("Disabling " . $plugin->getDescription()->getFullName());
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent(new PluginDisableEvent($plugin));
|
||||
|
||||
|
@ -241,7 +241,7 @@ abstract class PluginBase implements Plugin{
|
||||
|
||||
public function saveConfig(){
|
||||
if($this->getConfig()->save() === false){
|
||||
console("[SEVERE] Could not save config to " . $this->configFile);
|
||||
$this->getLogger()->critical("Could not save config to " . $this->configFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,14 @@
|
||||
|
||||
namespace pocketmine\plugin;
|
||||
|
||||
class PluginLogger{
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Logger;
|
||||
use pocketmine\utils\LogLevel;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class PluginLogger implements Logger{
|
||||
|
||||
private $pluginName;
|
||||
|
||||
@ -33,12 +40,39 @@ class PluginLogger{
|
||||
$this->pluginName = $prefix != null ? "[$prefix] " : "[" . $context->getDescription()->getName() . "] ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message to the console
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function log($message){
|
||||
console($this->pluginName . $message);
|
||||
public function emergency($message){
|
||||
$this->log(LogLevel::EMERGENCY, $message);
|
||||
}
|
||||
|
||||
public function alert($message){
|
||||
$this->log(LogLevel::ALERT, $message);
|
||||
}
|
||||
|
||||
public function critical($message){
|
||||
$this->log(LogLevel::CRITICAL, $message);
|
||||
}
|
||||
|
||||
public function error($message){
|
||||
$this->log(LogLevel::ERROR, $message);
|
||||
}
|
||||
|
||||
public function warning($message){
|
||||
$this->log(LogLevel::WARNING, $message);
|
||||
}
|
||||
|
||||
public function notice($message){
|
||||
$this->log(LogLevel::NOTICE, $message);
|
||||
}
|
||||
|
||||
public function info($message){
|
||||
$this->log(LogLevel::INFO, $message);
|
||||
}
|
||||
|
||||
public function debug($message){
|
||||
$this->log(LogLevel::DEBUG, $message);
|
||||
}
|
||||
|
||||
public function log($level, $message){
|
||||
MainLogger::getLogger()->log($level, $this->pluginName . $message);
|
||||
}
|
||||
}
|
@ -189,14 +189,14 @@ class PluginManager{
|
||||
if($description instanceof PluginDescription){
|
||||
$name = $description->getName();
|
||||
if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){
|
||||
console("[ERROR] Could not load plugin '" . $name . "': restricted name");
|
||||
$this->server->getLogger()->error("Could not load plugin '" . $name . "': restricted name");
|
||||
continue;
|
||||
}elseif(strpos($name, " ") !== false){
|
||||
console("[WARNING] Plugin '" . $name . "' uses spaces in its name, this is discouraged");
|
||||
$this->server->getLogger()->warning("Plugin '" . $name . "' uses spaces in its name, this is discouraged");
|
||||
}
|
||||
|
||||
if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){
|
||||
console("[ERROR] Could not load duplicate plugin '" . $name . "': plugin exists");
|
||||
$this->server->getLogger()->error("Could not load duplicate plugin '" . $name . "': plugin exists");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ class PluginManager{
|
||||
}
|
||||
|
||||
if($compatible === false){
|
||||
console("[ERROR] Could not load plugin '" . $name . "': API version not compatible");
|
||||
$this->server->getLogger()->error("Could not load plugin '" . $name . "': API version not compatible");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ class PluginManager{
|
||||
if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){
|
||||
unset($dependencies[$name][$key]);
|
||||
}elseif(!isset($plugins[$dependency])){
|
||||
console("[SEVERE] Could not load plugin '" . $name . "': Unknown dependency");
|
||||
$this->server->getLogger()->critical("Could not load plugin '" . $name . "': Unknown dependency");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ class PluginManager{
|
||||
if($plugin = $this->loadPlugin($file) and $plugin instanceof Plugin){
|
||||
$loadedPlugins[$name] = $plugin;
|
||||
}else{
|
||||
console("[SEVERE] Could not load plugin '" . $name . "'");
|
||||
$this->server->getLogger()->critical("Could not load plugin '" . $name . "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -291,7 +291,7 @@ class PluginManager{
|
||||
if($plugin = $this->loadPlugin($file) and $plugin instanceof Plugin){
|
||||
$loadedPlugins[$name] = $plugin;
|
||||
}else{
|
||||
console("[SEVERE] Could not load plugin '" . $name . "'");
|
||||
$this->server->getLogger()->critical("Could not load plugin '" . $name . "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -299,7 +299,7 @@ class PluginManager{
|
||||
//No plugins loaded :(
|
||||
if($missingDependency === true){
|
||||
foreach($plugins as $name => $file){
|
||||
console("[SEVERE] Could not load plugin '" . $name . "': circular dependency detected");
|
||||
$this->server->getLogger()->critical("Could not load plugin '" . $name . "': circular dependency detected");
|
||||
}
|
||||
$plugins = [];
|
||||
}
|
||||
@ -542,7 +542,7 @@ class PluginManager{
|
||||
|
||||
foreach($plugin->getDescription()->getCommands() as $key => $data){
|
||||
if(strpos($key, ":") !== false){
|
||||
console("[SEVERE] Could not load command " . $key . " for plugin " . $plugin->getDescription()->getName());
|
||||
$this->server->getLogger()->critical("Could not load command " . $key . " for plugin " . $plugin->getDescription()->getName());
|
||||
continue;
|
||||
}
|
||||
if(is_array($data)){
|
||||
@ -559,7 +559,7 @@ class PluginManager{
|
||||
$aliasList = [];
|
||||
foreach($data["aliases"] as $alias){
|
||||
if(strpos($alias, ":") !== false){
|
||||
console("[SEVERE] Could not load alias " . $alias . " for plugin " . $plugin->getDescription()->getName());
|
||||
$this->server->getLogger()->critical("Could not load alias " . $alias . " for plugin " . $plugin->getDescription()->getName());
|
||||
continue;
|
||||
}
|
||||
$aliasList[] = $alias;
|
||||
|
@ -410,7 +410,7 @@ class Config{
|
||||
break;
|
||||
}
|
||||
if(isset($this->config[$k])){
|
||||
console("[NOTICE] [Config] Repeated property " . $k . " on file " . $this->file, true, true, 2);
|
||||
MainLogger::getLogger()->debug("[Config] Repeated property " . $k . " on file " . $this->file);
|
||||
}
|
||||
$this->config[$k] = $v;
|
||||
}
|
||||
|
33
src/pocketmine/utils/LogLevel.php
Normal file
33
src/pocketmine/utils/LogLevel.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
interface LogLevel{
|
||||
const EMERGENCY = "emergency";
|
||||
const ALERT = "alert";
|
||||
const CRITICAL = "critical";
|
||||
const ERROR = "error";
|
||||
const WARNING = "warning";
|
||||
const NOTICE = "notice";
|
||||
const INFO = "info";
|
||||
const DEBUG = "debug";
|
||||
}
|
93
src/pocketmine/utils/Logger.php
Normal file
93
src/pocketmine/utils/Logger.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
interface Logger{
|
||||
|
||||
/**
|
||||
* System is unusable
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function emergency($message);
|
||||
|
||||
/**
|
||||
* Action must me taken immediately
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function alert($message);
|
||||
|
||||
/**
|
||||
* Critical conditions
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function critical($message);
|
||||
|
||||
/**
|
||||
* Runtime errors that do not require immediate action but should typically
|
||||
* be logged and monitored.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function error($message);
|
||||
|
||||
/**
|
||||
* Exceptional occurrences that are not errors.
|
||||
*
|
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
||||
* that are not necessarily wrong.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function warning($message);
|
||||
|
||||
/**
|
||||
* Normal but significant events.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function notice($message);
|
||||
|
||||
/**
|
||||
* Inersting events.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function info($message);
|
||||
|
||||
/**
|
||||
* Detailed debug information.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function debug($message);
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
*/
|
||||
public function log($level, $message);
|
||||
}
|
163
src/pocketmine/utils/MainLogger.php
Normal file
163
src/pocketmine/utils/MainLogger.php
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
class MainLogger extends \Thread implements Logger{
|
||||
protected $logFile;
|
||||
protected $logStream;
|
||||
protected $shutdown;
|
||||
protected $hasANSI;
|
||||
private $logResource;
|
||||
/** @var MainLogger */
|
||||
public static $logger = null;
|
||||
|
||||
/**
|
||||
* @param string $logFile
|
||||
* @param bool $hasANSI
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($logFile, $hasANSI = false){
|
||||
if(static::$logger instanceof MainLogger){
|
||||
throw new \RuntimeException("MainLogger has been already created");
|
||||
}
|
||||
static::$logger = $this;
|
||||
@mkdir(basename($logFile), 0777, true);
|
||||
$this->logFile = $logFile;
|
||||
$this->hasANSI = (bool) $hasANSI;
|
||||
$this->logStream = "";
|
||||
$this->start(PTHREADS_INHERIT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MainLogger
|
||||
*/
|
||||
public static function getLogger(){
|
||||
return static::$logger;
|
||||
}
|
||||
|
||||
public function emergency($message){
|
||||
$this->send(TextFormat::RED . "[EMERGENCY] ". $message);
|
||||
}
|
||||
|
||||
public function alert($message){
|
||||
$this->send(TextFormat::RED . "[ALERT] ". $message);
|
||||
}
|
||||
|
||||
public function critical($message){
|
||||
$this->send(TextFormat::RED . "[CRITICAL] ". $message);
|
||||
}
|
||||
|
||||
public function error($message){
|
||||
$this->send(TextFormat::DARK_RED . "[ERROR] ". $message);
|
||||
}
|
||||
|
||||
public function warning($message){
|
||||
$this->send(TextFormat::YELLOW . "[WARNING] ". $message);
|
||||
}
|
||||
|
||||
public function notice($message){
|
||||
$this->send(TextFormat::AQUA . "[NOTICE] ". $message);
|
||||
}
|
||||
|
||||
public function info($message){
|
||||
$this->send(TextFormat::WHITE . "[INFO] ". $message);
|
||||
}
|
||||
|
||||
public function debug($message){
|
||||
$this->send(TextFormat::GRAY . "[DEBUG] ". $message);
|
||||
}
|
||||
|
||||
public function log($level, $message){
|
||||
switch($level){
|
||||
case LogLevel::EMERGENCY:
|
||||
$this->emergency($message);
|
||||
break;
|
||||
case LogLevel::ALERT:
|
||||
$this->alert($message);
|
||||
break;
|
||||
case LogLevel::CRITICAL:
|
||||
$this->critical($message);
|
||||
break;
|
||||
case LogLevel::ERROR:
|
||||
$this->error($message);
|
||||
break;
|
||||
case LogLevel::WARNING:
|
||||
$this->warning($message);
|
||||
break;
|
||||
case LogLevel::NOTICE:
|
||||
$this->notice($message);
|
||||
break;
|
||||
case LogLevel::INFO:
|
||||
$this->info($message);
|
||||
break;
|
||||
case LogLevel::DEBUG:
|
||||
$this->debug($message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function shutdown(){
|
||||
$this->shutdown = true;
|
||||
}
|
||||
|
||||
protected function send($message){
|
||||
$now = time();
|
||||
$message = TextFormat::toANSI(TextFormat::AQUA . date("H:i:s", $now) . TextFormat::RESET . " " . $message . TextFormat::RESET . PHP_EOL);
|
||||
$cleanMessage = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $message));
|
||||
|
||||
if(!$this->hasANSI){
|
||||
echo $cleanMessage;
|
||||
}else{
|
||||
echo $message;
|
||||
}
|
||||
$this->logStream .= date("Y-m-d", $now) . " " . $cleanMessage;
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$this->shutdown = false;
|
||||
$this->logResource = fopen($this->logFile, "a+b");
|
||||
if(!is_resource($this->logResource)){
|
||||
throw new \RuntimeException("Couldn't open log file");
|
||||
}
|
||||
flock($this->logResource, LOCK_EX);
|
||||
|
||||
while($this->shutdown === false){
|
||||
if(strlen($this->logStream) >= 4096){
|
||||
$this->synchronized(function(){
|
||||
$chunks = strlen($this->logStream) >> 12;
|
||||
$chunk = substr($this->logStream, 0, $chunks << 12);
|
||||
$this->logStream = substr($this->logStream, $chunks << 12);
|
||||
fwrite($this->logResource, $chunk);
|
||||
});
|
||||
}else{
|
||||
usleep(250000); //sleep for 0.25 seconds
|
||||
}
|
||||
}
|
||||
if(strlen($this->logStream) > 0){
|
||||
fwrite($this->logResource, $this->logStream);
|
||||
}
|
||||
|
||||
flock($this->logResource, LOCK_UN);
|
||||
fclose($this->logResource);
|
||||
}
|
||||
}
|
163
src/pocketmine/utils/mainLogger.php
Normal file
163
src/pocketmine/utils/mainLogger.php
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
class MainLogger extends \Thread implements Logger{
|
||||
protected $logFile;
|
||||
protected $logStream;
|
||||
protected $shutdown;
|
||||
protected $hasANSI;
|
||||
private $logResource;
|
||||
/** @var MainLogger */
|
||||
public static $logger = null;
|
||||
|
||||
/**
|
||||
* @param string $logFile
|
||||
* @param bool $hasANSI
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($logFile, $hasANSI = false){
|
||||
if(static::$logger instanceof MainLogger){
|
||||
throw new \RuntimeException("MainLogger has been already created");
|
||||
}
|
||||
static::$logger = $this;
|
||||
@mkdir(basename($logFile), 0777, true);
|
||||
$this->logFile = $logFile;
|
||||
$this->hasANSI = (bool) $hasANSI;
|
||||
$this->logStream = "";
|
||||
$this->start(PTHREADS_INHERIT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MainLogger
|
||||
*/
|
||||
public static function getLogger(){
|
||||
return static::$logger;
|
||||
}
|
||||
|
||||
public function emergency($message){
|
||||
$this->send(TextFormat::RED . "[EMERGENCY] ". $message);
|
||||
}
|
||||
|
||||
public function alert($message){
|
||||
$this->send(TextFormat::RED . "[ALERT] ". $message);
|
||||
}
|
||||
|
||||
public function critical($message){
|
||||
$this->send(TextFormat::RED . "[CRITICAL] ". $message);
|
||||
}
|
||||
|
||||
public function error($message){
|
||||
$this->send(TextFormat::DARK_RED . "[ERROR] ". $message);
|
||||
}
|
||||
|
||||
public function warning($message){
|
||||
$this->send(TextFormat::YELLOW . "[WARNING] ". $message);
|
||||
}
|
||||
|
||||
public function notice($message){
|
||||
$this->send(TextFormat::AQUA . "[NOTICE] ". $message);
|
||||
}
|
||||
|
||||
public function info($message){
|
||||
$this->send(TextFormat::WHITE . "[INFO] ". $message);
|
||||
}
|
||||
|
||||
public function debug($message){
|
||||
$this->send(TextFormat::GRAY . "[DEBUG] ". $message);
|
||||
}
|
||||
|
||||
public function log($level, $message){
|
||||
switch($level){
|
||||
case LogLevel::EMERGENCY:
|
||||
$this->emergency($message);
|
||||
break;
|
||||
case LogLevel::ALERT:
|
||||
$this->alert($message);
|
||||
break;
|
||||
case LogLevel::CRITICAL:
|
||||
$this->critical($message);
|
||||
break;
|
||||
case LogLevel::ERROR:
|
||||
$this->error($message);
|
||||
break;
|
||||
case LogLevel::WARNING:
|
||||
$this->warning($message);
|
||||
break;
|
||||
case LogLevel::NOTICE:
|
||||
$this->notice($message);
|
||||
break;
|
||||
case LogLevel::INFO:
|
||||
$this->info($message);
|
||||
break;
|
||||
case LogLevel::DEBUG:
|
||||
$this->debug($message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function shutdown(){
|
||||
$this->shutdown = true;
|
||||
}
|
||||
|
||||
protected function send($message){
|
||||
$now = time();
|
||||
$message = TextFormat::toANSI(TextFormat::AQUA . date("H:i:s", $now) . TextFormat::RESET . " " . $message . TextFormat::RESET . PHP_EOL);
|
||||
$cleanMessage = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $message));
|
||||
|
||||
if(!$this->hasANSI){
|
||||
echo $cleanMessage;
|
||||
}else{
|
||||
echo $message;
|
||||
}
|
||||
$this->logStream .= date("Y-m-d", $now) . " " . $cleanMessage;
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$this->shutdown = false;
|
||||
$this->logResource = fopen($this->logFile, "a+b");
|
||||
if(!is_resource($this->logResource)){
|
||||
throw new \RuntimeException("Couldn't open log file");
|
||||
}
|
||||
flock($this->logResource, LOCK_EX);
|
||||
|
||||
while($this->shutdown === false){
|
||||
if(strlen($this->logStream) >= 4096){
|
||||
$this->synchronized(function(){
|
||||
$chunks = strlen($this->logStream) >> 12;
|
||||
$chunk = substr($this->logStream, 0, $chunks << 12);
|
||||
$this->logStream = substr($this->logStream, $chunks << 12);
|
||||
fwrite($this->logResource, $chunk);
|
||||
});
|
||||
}else{
|
||||
usleep(250000); //sleep for 0.25 seconds
|
||||
}
|
||||
}
|
||||
if(strlen($this->logStream) > 0){
|
||||
fwrite($this->logResource, $this->logStream);
|
||||
}
|
||||
|
||||
flock($this->logResource, LOCK_UN);
|
||||
fclose($this->logResource);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user