public function trigger($memory, $limit, $global = false, $triggerCount = 0) { $this->server->getLogger()->debug("[Memory Manager] " . ($global ? "Global " : "") . "Low memory triggered, limit " . round($limit / 1024 / 1024, 2) . "MB, using " . round($memory / 1024 / 1024, 2) . "MB"); if ($this->cacheTrigger) { foreach ($this->server->getLevels() as $level) { $level->clearCache(true); } } if ($this->chunkTrigger and $this->chunkCollect) { foreach ($this->server->getLevels() as $level) { $level->doChunkGarbageCollection(); } } $ev = new LowMemoryEvent($memory, $limit, $global, $triggerCount); $this->server->getPluginManager()->callEvent($ev); $cycles = 0; if ($this->garbageCollectionTrigger) { $cycles = $this->triggerGarbageCollector(); } $this->server->getLogger()->debug("[Memory Manager] Freed " . round($ev->getMemoryFreed() / 1024 / 1024, 2) . "MB, {$cycles} cycles"); }
/** * Call a plugin's function. * * If the $plug parameter is given a string, it will simply look for that * plugin. If an array is provided, it is assumed to be of the form: * * [ "plugin", "version" ] * * So then it will check that the plugin exists, and the version number * matches according to the rules from **apiCheck**. * * Also, if plugin contains an **api** property, it will use that as * the class for method calling instead. * * @param Server $server - pocketmine server instance * @param str|array $plug - plugin to call * @param str $method - method to call * @param mixed $default - If the plugin does not exist or it is not enable, this value is returned * @return mixed */ public static function callPlugin($server, $plug, $method, $args, $default = null) { $v = null; if (is_array($plug)) { list($plug, $v) = $plug; } if (($plugin = $server->getPluginManager()->getPlugin($plug)) === null || !$plugin->isEnabled()) { return $default; } if ($v !== null && !self::apiCheck($plugin->getDescription()->getVersion(), $v)) { return $default; } if (property_exists($plugin, "api")) { $fn = [$plugin->api, $method]; } else { $fn = [$plugin, $method]; } if (!is_callable($fn)) { return $default; } return $fn(...$args); }
/** * Call a plugin's function * * @param Server $server - pocketmine server instance * @param str $plug - plugin to call * @param str $method - method to call * @param mixed $default - If the plugin does not exist or it is not enable, this value uis returned * @return mixed */ public static function callPlugin($server, $plug, $method, $args, $default = null) { if (($plugin = $server->getPluginManager()->getPlugin($plug)) !== null && $plugin->isEnabled()) { $fn = [$plugin, $method]; return $fn(...$args); } return $default; }
private function baseCrash() { global $lastExceptionError, $lastError; if (isset($lastExceptionError)) { $error = $lastExceptionError; } else { $error = (array) error_get_last(); $error["trace"] = @getTrace(3); $errorConversion = [E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_DEPRECATED => "E_DEPRECATED", E_USER_DEPRECATED => "E_USER_DEPRECATED"]; $error["fullFile"] = $error["file"]; $error["file"] = cleanPath($error["file"]); $error["type"] = isset($errorConversion[$error["type"]]) ? $errorConversion[$error["type"]] : $error["type"]; if (($pos = strpos($error["message"], "\n")) !== false) { $error["message"] = substr($error["message"], 0, $pos); } } if (isset($lastError)) { $this->data["lastError"] = $lastError; } $this->data["error"] = $error; unset($this->data["error"]["fullFile"]); unset($this->data["error"]["trace"]); $this->addLine("Error: " . $error["message"]); $this->addLine("File: " . $error["file"]); $this->addLine("Line: " . $error["line"]); $this->addLine("Type: " . $error["type"]); if (strpos($error["file"], "src/BukkitPE/") === false and strpos($error["file"], "src/raklib/") === false and file_exists($error["fullFile"])) { $this->addLine(); $this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN"); $this->data["plugin"] = true; $reflection = new \ReflectionClass(PluginBase::class); $file = $reflection->getProperty("file"); $file->setAccessible(true); foreach ($this->server->getPluginManager()->getPlugins() as $plugin) { $filePath = \BukkitPE\cleanPath($file->getValue($plugin)); if (strpos($error["file"], $filePath) === 0) { $this->data["plugin"] = $plugin->getName(); $this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName()); break; } } } else { $this->data["plugin"] = false; } $this->addLine(); $this->addLine("Code:"); $this->data["code"] = []; if ($this->server->getProperty("auto-report.send-code", true) !== false) { $file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES); for ($l = max(0, $error["line"] - 10); $l < $error["line"] + 10; ++$l) { $this->addLine("[" . ($l + 1) . "] " . @$file[$l]); $this->data["code"][$l + 1] = @$file[$l]; } } $this->addLine(); $this->addLine("Backtrace:"); foreach ($this->data["trace"] = $error["trace"] as $line) { $this->addLine($line); } $this->addLine(); }