diff --git a/src/API/ServerAPI.php b/src/API/ServerAPI.php index 8a999a593..2126e4dca 100644 --- a/src/API/ServerAPI.php +++ b/src/API/ServerAPI.php @@ -98,6 +98,15 @@ class ServerAPI{ @mkdir(DATA_PATH."players/", 0755); @mkdir(DATA_PATH."worlds/", 0755); @mkdir(DATA_PATH."plugins/", 0755); + + //Init all the events + foreach(get_declared_classes() as $class){ + if(is_subclass_of($class, "BaseEvent") and property_exists($class, "handlers") and property_exists($class, "handlerPriority")){ + echo $class; + $class::unregisterAll(); + } + } + $version = new VersionString(); console("[INFO] Starting Minecraft PE server version ".FORMAT_AQUA.CURRENT_MINECRAFT_VERSION); diff --git a/src/event/BaseEvent.php b/src/event/BaseEvent.php index 9a73cfeb5..679739c43 100644 --- a/src/event/BaseEvent.php +++ b/src/event/BaseEvent.php @@ -25,8 +25,18 @@ abstract class BaseEvent{ const NORMAL = 2; const FORCE = 0x80000000; + /** + * Any callable event must declare the static variables + * + * private static $handlers; + * private static $handlerPriority; + * + * Not doing so will deny the proper event initialization + */ + protected $eventName = null; private $status = BaseEvent::NORMAL; + private $prioritySlot; final public function getEventName(){ return $this->eventName !== null ? get_class($this) : $this->eventName; @@ -42,15 +52,71 @@ abstract class BaseEvent{ public function isAllowed(){ - return $this->status === BaseEvent::ALLOW; + return ($this->status & 0x7FFFFFFF) === BaseEvent::ALLOW; } public function setAllowed($forceAllow = false){ $this->status = BaseEvent::ALLOW & ($forceAllow === true ? BaseEvent::FORCE : 0); } + public function isNormal(){ + return $this->status === BaseEvent::NORMAL; + } + + public function setNormal(){ + $this->status = BaseEvent::NORMAL; + } + public function isForced(){ return ($this->status & BaseEvent::FORCE) > 0; } - + + public static function getHandlerList(){ + return self::$handlers; + } + + public static function getPriorityList(){ + return self::$handlerPriority; + } + + public static function unregisterAll(){ + self::$handlers = array(); + self::$handlerPriority = array( + EventPriority::LOWEST => array(), + EventPriority::LOW => array(), + EventPriority::NORMAL => array(), + EventPriority::HIGH => array(), + EventPriority::HIGHEST => array(), + EventPriority::MONITOR => array() + ); + } + + public function register(callable $handler, $priority = EventPriority::NORMAL){ + $identifier = Utils::getCallableIdentifier($handler); + if(isset(self::$handlers[$identifier])){ //Already registered + return false; + }else{ + self::$handlers[$identifier] = $handler; + self::$handlerPriority[(int) $priority][$identifier] = $handler; + return true; + } + } + + public function unregister(callable $handler, $priority = EventPriority::NORMAL){ + $identifier = Utils::getCallableIdentifier($handler); + if(isset(self::$handlers[$identifier])){ + if(isset(self::$handlerPriority[(int) $priority][$identifier])){ + unset(self::$handlerPriority[(int) $priority][$identifier]); + }else{ + for($priority = EventPriority::MONITOR; $priority <= EventPriority::LOWEST; ++$priority){ + unset(self::$handlerPriority[$priority][$identifier]); + } + } + unset(self::$handlers[$identifier]); + return true; + }else{ + return false; + } + } + } \ No newline at end of file diff --git a/src/event/CancellableEvent.php b/src/event/CancellableEvent.php index 5d3fab8f0..affb4132a 100644 --- a/src/event/CancellableEvent.php +++ b/src/event/CancellableEvent.php @@ -21,7 +21,7 @@ abstract class CancellableEvent extends BaseEvent{ public function isCancelled(){ - return $this->status === BaseEvent::DENY; + return ($this->status & 0x7FFFFFFF) === BaseEvent::DENY; } public function setCancelled($forceCancel = false){ diff --git a/src/event/EventHandler.php b/src/event/EventHandler.php new file mode 100644 index 000000000..50166b943 --- /dev/null +++ b/src/event/EventHandler.php @@ -0,0 +1,50 @@ + $handlerList){ + if(count($handlerList) > 0){ + $event->setPrioritySlot($priority); + foreach($handlerList as $handler){ + call_user_func($handler, $event); + } + if($event->isForced()){ + if($event instanceof CancellableEvent and $event->isCancelled()){ + return BaseEvent::DENY; + }else{ + return BaseEvent::ALLOW; + } + } + } + } + if($event instanceof CancellableEvent and $event->isCancelled()){ + return BaseEvent::DENY; + }elseif($event->isAllowed()){ + return BaseEvent::ALLOW; + }else{ + return BaseEvent::NORMAL; + } + } + +} \ No newline at end of file diff --git a/src/utils/Utils.php b/src/utils/Utils.php index c25597941..510337d81 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -31,6 +31,14 @@ class Utils{ return ((@fsockopen("8.8.8.8", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.linux.org", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.php.net", 80, $e = null, $n = null, 2) !== false) ? true:false); } + public static function getCallableIdentifier(callable $variable){ + if(is_array($variable)){ + return sha1(strtolower(get_class($variable))."::".strtolower($variable[1])); + }else{ + return sha1(strtolower($variable)); + } + } + public static function getUniqueID($raw = false, $extra = ""){ $machine = php_uname("a"); $machine .= file_exists("/proc/cpuinfo") ? file_get_contents("/proc/cpuinfo") : "";