Added Error -> Exception handling

This commit is contained in:
Shoghi Cervantes 2014-10-28 20:43:36 +01:00
parent 0fce83c671
commit b6f7ee20fc
11 changed files with 114 additions and 76 deletions

View File

@ -1474,9 +1474,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$newPos = new Vector3($packet->x, $packet->y, $packet->z); $newPos = new Vector3($packet->x, $packet->y, $packet->z);
$revert = ($this->dead === true or $this->spawned !== true); $revert = false;
if($this->dead === true or $this->spawned !== true){
$revert = true;
$this->forceMovement = new Vector3($this->x, $this->y, $this->z);
}
if($revert or ($this->forceMovement instanceof Vector3 and $newPos->distance($this->forceMovement) > 0.2)){ if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distance($this->forceMovement) > 0.2)){
$pk = MovePlayerPacket::getFromPool(); $pk = MovePlayerPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $this->x; $pk->x = $this->x;

View File

@ -327,55 +327,7 @@ namespace pocketmine {
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/"); return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
} }
function error_handler($errno, $errstr, $errfile, $errline, $context, $trace = null){ set_error_handler([\ExceptionHandler::class, "handler"], -1);
global $lastError;
if(error_reporting() === 0){ //@ error-con..trol
return false;
}
$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",
];
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE);
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$logger = MainLogger::getLogger();
$oldFile = $errfile;
$errfile = cleanPath($errfile);
$logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
foreach(($trace = getTrace($trace === null ? 3 : 0, $trace)) as $i => $line){
$logger->debug($line);
}
$lastError = [
"type" => $type,
"message" => $errstr,
"fullFile" => $oldFile,
"file" => $errfile,
"line" => $errline,
"trace" => $trace
];
return true;
}
set_error_handler("\\pocketmine\\error_handler", E_ALL);
$errors = 0; $errors = 0;

View File

@ -1950,12 +1950,38 @@ class Server{
} }
} }
public function exceptionHandler(\Exception $e){ public function exceptionHandler(\Exception $e, $trace = null){
if($e === null){ if($e === null){
return; return;
} }
error_handler(E_ERROR, $e->getMessage(), $e->getFile(), $e->getLine(), [], $e->getTrace()); global $lastError;
$errstr = $e->getMessage();
$errfile = $e->getFile();
$errno = $e->getCode();
$errline = $e->getLine();
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? \LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? \LogLevel::WARNING : \LogLevel::NOTICE);
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$errfile = cleanPath($errfile);
if($this->logger instanceof MainLogger){
$this->logger->logException($e, $trace);
}
$lastError = [
"type" => $type,
"message" => $errstr,
"fullFile" => $e->getFile(),
"file" => $errfile,
"line" => $errline,
"trace" => getTrace($trace === null ? 3 : 0, $trace)
];
global $lastExceptionError, $lastError; global $lastExceptionError, $lastError;
$lastExceptionError = $lastError; $lastExceptionError = $lastError;
$this->crashDump(); $this->crashDump();

View File

@ -63,7 +63,7 @@ abstract class Fallable extends Solid{
new Float("", 0) new Float("", 0)
]), ]),
"TileID" => new Int("TileID", $this->getID()), "TileID" => new Int("TileID", $this->getID()),
"TileData" => new Byte("TileData", $this->getDamage()), "Data" => new Byte("Data", $this->getDamage()),
])); ]));
$fall->spawnToAll(); $fall->spawnToAll();

View File

@ -26,7 +26,7 @@ use pocketmine\block\Block;
use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityBlockChangeEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Int;
@ -58,8 +58,8 @@ class FallingSand extends Entity{
$this->namedtag["TileID"] = new Int("TileID", $this->blockId); $this->namedtag["TileID"] = new Int("TileID", $this->blockId);
} }
if(isset($this->namedtag->TileData)){ if(isset($this->namedtag->Data)){
$this->damage = $this->namedtag["TileData"]; $this->damage = $this->namedtag["Data"];
} }
if($this->blockId === 0){ if($this->blockId === 0){
@ -115,7 +115,7 @@ class FallingSand extends Entity{
$this->kill(); $this->kill();
$block = $this->level->getBlock($pos); $block = $this->level->getBlock($pos);
if(!$block->isFullBlock){ if(!$block->isFullBlock){
$this->getLevel()->dropItem($this, Item::get($this->getBlock(), $this->getDamage(), 1)); $this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1));
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = EntityBlockChangeEvent::createEvent($this, $block, Block::get($this->getBlock(), $this->getDamage()))); $this->server->getPluginManager()->callEvent($ev = EntityBlockChangeEvent::createEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\inventory\PlayerInventory; use pocketmine\inventory\PlayerInventory;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
@ -67,9 +67,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1); $this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor }elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
$this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, Item::get($item["id"], $item["Damage"], $item["Count"]), $this); $this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, ItemItem::get($item["id"], $item["Damage"], $item["Count"]), $this);
}else{ }else{
$this->inventory->setItem($item["Slot"] - 9, Item::get($item["id"], $item["Damage"], $item["Count"]), $this); $this->inventory->setItem($item["Slot"] - 9, ItemItem::get($item["id"], $item["Damage"], $item["Count"]), $this);
} }
} }
@ -140,7 +140,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
//Armor //Armor
for($slot = 100; $slot < 104; ++$slot){ for($slot = 100; $slot < 104; ++$slot){
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100); $item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
if($item instanceof Item and $item->getID() !== Item::AIR){ if($item instanceof ItemItem and $item->getID() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = new Compound(false, [ $this->namedtag->Inventory[$slot] = new Compound(false, [
new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()), new Short("Damage", $item->getDamage()),

View File

@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityDeathEvent; use pocketmine\event\entity\EntityDeathEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\Timings; use pocketmine\event\Timings;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\EntityEventPacket;
@ -163,7 +163,7 @@ abstract class Living extends Entity implements Damageable{
} }
/** /**
* @return Item[] * @return ItemItem[]
*/ */
public function getDrops(){ public function getDrops(){
return []; return [];

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddMobPacket; use pocketmine\network\protocol\AddMobPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
@ -83,19 +83,19 @@ class Zombie extends Monster{
public function getDrops(){ public function getDrops(){
$drops = [ $drops = [
Item::get(Item::FEATHER, 0, 1) ItemItem::get(Item::FEATHER, 0, 1)
]; ];
if($this->lastDamageCause instanceof EntityDamageByEntityEvent and $this->lastDamageCause->getEntity() instanceof Player){ if($this->lastDamageCause instanceof EntityDamageByEntityEvent and $this->lastDamageCause->getEntity() instanceof Player){
if(mt_rand(0, 199) < 5){ if(mt_rand(0, 199) < 5){
switch(mt_rand(0, 2)){ switch(mt_rand(0, 2)){
case 0: case 0:
$drops[] = Item::get(Item::IRON_INGOT, 0, 1); $drops[] = ItemItem::get(ItemItem::IRON_INGOT, 0, 1);
break; break;
case 1: case 1:
$drops[] = Item::get(Item::CARROT, 0, 1); $drops[] = ItemItem::get(ItemItem::CARROT, 0, 1);
break; break;
case 2: case 2:
$drops[] = Item::get(Item::POTATO, 0, 1); $drops[] = ItemItem::get(ItemItem::POTATO, 0, 1);
break; break;
} }
} }

View File

@ -33,6 +33,7 @@ use pocketmine\event\TimingsHandler;
use pocketmine\permission\Permissible; use pocketmine\permission\Permissible;
use pocketmine\permission\Permission; use pocketmine\permission\Permission;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\MainLogger;
/** /**
* Manages all the plugins, Permissions and Permissibles * Manages all the plugins, Permissions and Permissibles
@ -546,12 +547,18 @@ class PluginManager{
*/ */
public function enablePlugin(Plugin $plugin){ public function enablePlugin(Plugin $plugin){
if(!$plugin->isEnabled()){ if(!$plugin->isEnabled()){
try{
foreach($plugin->getDescription()->getPermissions() as $perm){ foreach($plugin->getDescription()->getPermissions() as $perm){
$this->addPermission($perm); $this->addPermission($perm);
} }
$plugin->getPluginLoader()->enablePlugin($plugin); $plugin->getPluginLoader()->enablePlugin($plugin);
}catch(\Exception $e){
$logger = Server::getInstance()->getLogger();
if($logger instanceof MainLogger){
$logger->logException($e);
}
$this->disablePlugin($plugin);
}
} }
} }
@ -617,7 +624,15 @@ class PluginManager{
*/ */
public function disablePlugin(Plugin $plugin){ public function disablePlugin(Plugin $plugin){
if($plugin->isEnabled()){ if($plugin->isEnabled()){
try{
$plugin->getPluginLoader()->disablePlugin($plugin); $plugin->getPluginLoader()->disablePlugin($plugin);
}catch(\Exception $e){
$logger = Server::getInstance()->getLogger();
if($logger instanceof MainLogger){
$logger->logException($e);
}
}
$this->server->getScheduler()->cancelTasks($plugin); $this->server->getScheduler()->cancelTasks($plugin);
HandlerList::unregisterAll($plugin); HandlerList::unregisterAll($plugin);
foreach($plugin->getDescription()->getPermissions() as $perm){ foreach($plugin->getDescription()->getPermissions() as $perm){

View File

@ -102,6 +102,47 @@ class MainLogger extends \AttachableThreadedLogger{
$this->logDebug = (bool) $logDebug; $this->logDebug = (bool) $logDebug;
} }
public function logException(\Exception $e, $trace = null){
$errstr = $e->getMessage();
$errfile = $e->getFile();
$errno = $e->getCode();
$errline = $e->getLine();
$errorConversion = [
0 => "EXCEPTION",
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",
];
if($errno === 0){
$type = LogLevel::CRITICAL;
}else{
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE);
}
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$errfile = \pocketmine\cleanPath($errfile);
$this->log($type, get_class($e).": \"$errstr\" ($errno) in \"$errfile\" at line $errline");
foreach(($trace = \pocketmine\getTrace($trace === null ? 4 : 0, $trace)) as $i => $line){
$this->debug($line);
}
}
public function log($level, $message){ public function log($level, $message){
switch($level){ switch($level){
case LogLevel::EMERGENCY: case LogLevel::EMERGENCY:

@ -1 +1 @@
Subproject commit dd275a8f9909cd1e52079173e4447c7a88d7e22e Subproject commit cccae3510b3e05def83a58323dc3b3878aa7b384