mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-11 00:09:39 +00:00
Merge branch '3.5'
This commit is contained in:
commit
3ae722867c
@ -87,7 +87,11 @@ class CrashDump{
|
|||||||
* having their content changed, version format changing, etc.
|
* having their content changed, version format changing, etc.
|
||||||
* It is not necessary to increase this when adding new fields.
|
* It is not necessary to increase this when adding new fields.
|
||||||
*/
|
*/
|
||||||
private const FORMAT_VERSION = 1;
|
private const FORMAT_VERSION = 2;
|
||||||
|
|
||||||
|
private const PLUGIN_INVOLVEMENT_NONE = "none";
|
||||||
|
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
|
||||||
|
private const PLUGIN_INVOLVEMENT_INDIRECT = "indirect";
|
||||||
|
|
||||||
/** @var Server */
|
/** @var Server */
|
||||||
private $server;
|
private $server;
|
||||||
@ -207,7 +211,7 @@ class CrashDump{
|
|||||||
$error = $lastExceptionError;
|
$error = $lastExceptionError;
|
||||||
}else{
|
}else{
|
||||||
$error = (array) error_get_last();
|
$error = (array) error_get_last();
|
||||||
$error["trace"] = Utils::printableCurrentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
$error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||||
$errorConversion = [
|
$errorConversion = [
|
||||||
E_ERROR => "E_ERROR",
|
E_ERROR => "E_ERROR",
|
||||||
E_WARNING => "E_WARNING",
|
E_WARNING => "E_WARNING",
|
||||||
@ -245,24 +249,16 @@ class CrashDump{
|
|||||||
$this->addLine("Line: " . $error["line"]);
|
$this->addLine("Line: " . $error["line"]);
|
||||||
$this->addLine("Type: " . $error["type"]);
|
$this->addLine("Type: " . $error["type"]);
|
||||||
|
|
||||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "vendor/pocketmine/") === false and file_exists($error["fullFile"])){
|
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_NONE;
|
||||||
$this->addLine();
|
if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace
|
||||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
foreach($error["trace"] as $frame){
|
||||||
$this->data["plugin"] = true;
|
if(!isset($frame["file"])){
|
||||||
|
continue; //PHP core
|
||||||
$reflection = new \ReflectionClass(PluginBase::class);
|
}
|
||||||
$file = $reflection->getProperty("file");
|
if($this->determinePluginFromFile($frame["file"], false)){
|
||||||
$file->setAccessible(true);
|
|
||||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
|
||||||
$filePath = Utils::cleanPath($file->getValue($plugin));
|
|
||||||
if(strpos($error["file"], $filePath) === 0){
|
|
||||||
$this->data["plugin"] = $plugin->getName();
|
|
||||||
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
$this->data["plugin"] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addLine();
|
$this->addLine();
|
||||||
@ -279,12 +275,40 @@ class CrashDump{
|
|||||||
|
|
||||||
$this->addLine();
|
$this->addLine();
|
||||||
$this->addLine("Backtrace:");
|
$this->addLine("Backtrace:");
|
||||||
foreach(($this->data["trace"] = $error["trace"]) as $line){
|
foreach(($this->data["trace"] = Utils::printableTrace($error["trace"])) as $line){
|
||||||
$this->addLine($line);
|
$this->addLine($line);
|
||||||
}
|
}
|
||||||
$this->addLine();
|
$this->addLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
|
||||||
|
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
|
||||||
|
if($frameCleanPath !== "" and strpos($frameCleanPath, "src/pocketmine/") === false and strpos($frameCleanPath, "vendor/pocketmine/") === false and file_exists($filePath)){
|
||||||
|
$this->addLine();
|
||||||
|
if($crashFrame){
|
||||||
|
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||||
|
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_DIRECT;
|
||||||
|
}else{
|
||||||
|
$this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH");
|
||||||
|
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflection = new \ReflectionClass(PluginBase::class);
|
||||||
|
$file = $reflection->getProperty("file");
|
||||||
|
$file->setAccessible(true);
|
||||||
|
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||||
|
$filePath = Utils::cleanPath($file->getValue($plugin));
|
||||||
|
if(strpos($frameCleanPath, $filePath) === 0){
|
||||||
|
$this->data["plugin"] = $plugin->getName();
|
||||||
|
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private function generalData(){
|
private function generalData(){
|
||||||
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
||||||
$this->data["general"] = [];
|
$this->data["general"] = [];
|
||||||
|
@ -104,7 +104,6 @@ use pocketmine\tile\Tile;
|
|||||||
use pocketmine\timings\Timings;
|
use pocketmine\timings\Timings;
|
||||||
use pocketmine\timings\TimingsHandler;
|
use pocketmine\timings\TimingsHandler;
|
||||||
use pocketmine\updater\AutoUpdater;
|
use pocketmine\updater\AutoUpdater;
|
||||||
use pocketmine\utils\Binary;
|
|
||||||
use pocketmine\utils\Config;
|
use pocketmine\utils\Config;
|
||||||
use pocketmine\utils\Internet;
|
use pocketmine\utils\Internet;
|
||||||
use pocketmine\utils\MainLogger;
|
use pocketmine\utils\MainLogger;
|
||||||
@ -151,6 +150,7 @@ use function pcntl_signal;
|
|||||||
use function pcntl_signal_dispatch;
|
use function pcntl_signal_dispatch;
|
||||||
use function preg_replace;
|
use function preg_replace;
|
||||||
use function random_bytes;
|
use function random_bytes;
|
||||||
|
use function random_int;
|
||||||
use function realpath;
|
use function realpath;
|
||||||
use function register_shutdown_function;
|
use function register_shutdown_function;
|
||||||
use function rename;
|
use function rename;
|
||||||
@ -169,6 +169,8 @@ use function time;
|
|||||||
use function touch;
|
use function touch;
|
||||||
use function trim;
|
use function trim;
|
||||||
use const DIRECTORY_SEPARATOR;
|
use const DIRECTORY_SEPARATOR;
|
||||||
|
use const INT32_MAX;
|
||||||
|
use const INT32_MIN;
|
||||||
use const PHP_EOL;
|
use const PHP_EOL;
|
||||||
use const PHP_INT_MAX;
|
use const PHP_INT_MAX;
|
||||||
use const PTHREADS_INHERIT_NONE;
|
use const PTHREADS_INHERIT_NONE;
|
||||||
@ -1120,7 +1122,7 @@ class Server{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$seed = $seed ?? Binary::readInt(random_bytes(4));
|
$seed = $seed ?? random_int(INT32_MIN, INT32_MAX);
|
||||||
|
|
||||||
if(!isset($options["preset"])){
|
if(!isset($options["preset"])){
|
||||||
$options["preset"] = $this->getConfigString("generator-settings", "");
|
$options["preset"] = $this->getConfigString("generator-settings", "");
|
||||||
@ -2273,7 +2275,7 @@ class Server{
|
|||||||
"fullFile" => $e->getFile(),
|
"fullFile" => $e->getFile(),
|
||||||
"file" => $errfile,
|
"file" => $errfile,
|
||||||
"line" => $errline,
|
"line" => $errline,
|
||||||
"trace" => Utils::printableTrace($trace)
|
"trace" => $trace
|
||||||
];
|
];
|
||||||
|
|
||||||
global $lastExceptionError, $lastError;
|
global $lastExceptionError, $lastError;
|
||||||
@ -2312,7 +2314,7 @@ class Server{
|
|||||||
if(is_string($plugin)){
|
if(is_string($plugin)){
|
||||||
$p = $this->pluginManager->getPlugin($plugin);
|
$p = $this->pluginManager->getPlugin($plugin);
|
||||||
if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){
|
if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){
|
||||||
$report = false;
|
$this->logger->debug("Not sending crashdump due to caused by non-phar plugin");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +578,21 @@ class Utils{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function cleanPath($path){
|
public static function cleanPath($path){
|
||||||
return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path);
|
$result = str_replace(["\\", ".php", "phar://"], ["/", "", ""], $path);
|
||||||
|
|
||||||
|
//remove relative paths
|
||||||
|
//TODO: make these paths dynamic so they can be unit-tested against
|
||||||
|
static $cleanPaths = [
|
||||||
|
\pocketmine\PLUGIN_PATH => "plugins", //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations
|
||||||
|
\pocketmine\PATH => ""
|
||||||
|
];
|
||||||
|
foreach($cleanPaths as $cleanPath => $replacement){
|
||||||
|
$cleanPath = rtrim(str_replace(["\\", "phar://"], ["/", ""], $cleanPath), "/");
|
||||||
|
if(strpos($result, $cleanPath) === 0){
|
||||||
|
$result = ltrim(str_replace($cleanPath, $replacement, $result), "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user