diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6db226009..66da88401 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -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 = []; diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index aac6477b2..772cdd870 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -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); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index cc4116b99..bdf2b82b6 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -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; diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 02beea79b..8ae7ed728 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -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); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 06b9db600..2404eba72 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -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(); diff --git a/src/pocketmine/level/LevelImport.php b/src/pocketmine/level/LevelImport.php index c71d90695..e9297aab6 100644 --- a/src/pocketmine/level/LevelImport.php +++ b/src/pocketmine/level/LevelImport.php @@ -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; diff --git a/src/pocketmine/level/format/PocketChunkParser.php b/src/pocketmine/level/format/PocketChunkParser.php index ee03c9fb4..70cb99c7e 100644 --- a/src/pocketmine/level/format/PocketChunkParser.php +++ b/src/pocketmine/level/format/PocketChunkParser.php @@ -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); } diff --git a/src/pocketmine/level/format/pmf/LevelFormat.php b/src/pocketmine/level/format/pmf/LevelFormat.php index 22e129e9d..04a645da0 100644 --- a/src/pocketmine/level/format/pmf/LevelFormat.php +++ b/src/pocketmine/level/format/pmf/LevelFormat.php @@ -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; diff --git a/src/pocketmine/level/format/pmf/PMF.php b/src/pocketmine/level/format/pmf/PMF.php index 61c5bed47..34cf1b302 100644 --- a/src/pocketmine/level/format/pmf/PMF.php +++ b/src/pocketmine/level/format/pmf/PMF.php @@ -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; } diff --git a/src/pocketmine/network/ThreadedHandler.php b/src/pocketmine/network/ThreadedHandler.php index 7c191cc26..eb9956fb9 100644 --- a/src/pocketmine/network/ThreadedHandler.php +++ b/src/pocketmine/network/ThreadedHandler.php @@ -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); diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 97210f699..642d2c5aa 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -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(){ diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 4b6494d22..dd739023a 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -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); diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index ca4eaa73a..5c4102152 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -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"); } } diff --git a/src/pocketmine/plugin/PharPluginLoader.php b/src/pocketmine/plugin/PharPluginLoader.php index 07558620c..0b779aab4 100644 --- a/src/pocketmine/plugin/PharPluginLoader.php +++ b/src/pocketmine/plugin/PharPluginLoader.php @@ -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)); diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 6aec80525..297ef34cb 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -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); } } diff --git a/src/pocketmine/plugin/PluginLogger.php b/src/pocketmine/plugin/PluginLogger.php index 02ec36535..a5d92656d 100644 --- a/src/pocketmine/plugin/PluginLogger.php +++ b/src/pocketmine/plugin/PluginLogger.php @@ -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); } } \ No newline at end of file diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 482560801..6c0bb1027 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -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; diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 761ea6d53..73e430571 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -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; } diff --git a/src/pocketmine/utils/LogLevel.php b/src/pocketmine/utils/LogLevel.php new file mode 100644 index 000000000..11336bb01 --- /dev/null +++ b/src/pocketmine/utils/LogLevel.php @@ -0,0 +1,33 @@ +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); + } +} \ No newline at end of file diff --git a/src/pocketmine/utils/mainLogger.php b/src/pocketmine/utils/mainLogger.php new file mode 100644 index 000000000..957a618b7 --- /dev/null +++ b/src/pocketmine/utils/mainLogger.php @@ -0,0 +1,163 @@ +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); + } +} \ No newline at end of file