<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit2465bc1320a965a378e5f39bc0181113::getLoader();
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit2465bc1320a965a378e5f39bc0181113
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit2465bc1320a965a378e5f39bc0181113', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit2465bc1320a965a378e5f39bc0181113', 'loadClassLoader'));

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require_once __DIR__ . '/autoload_static.php';

            call_user_func(\Composer\Autoload\ComposerStaticInit2465bc1320a965a378e5f39bc0181113::getInitializer($loader));
        } else {
            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
        }

        $loader->setClassMapAuthoritative(true);
        $loader->register(true);

        if ($useStaticLoader) {
            $includeFiles = Composer\Autoload\ComposerStaticInit2465bc1320a965a378e5f39bc0181113::$files;
        } else {
            $includeFiles = require __DIR__ . '/autoload_files.php';
        }
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequire2465bc1320a965a378e5f39bc0181113($fileIdentifier, $file);
        }

        return $loader;
    }
}

function composerRequire2465bc1320a965a378e5f39bc0181113($fileIdentifier, $file)
{
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        require $file;

        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
    }
}
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Autoload;

/**
 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 *
 *     $loader = new \Composer\Autoload\ClassLoader();
 *
 *     // register classes with namespaces
 *     $loader->add('Symfony\Component', __DIR__.'/component');
 *     $loader->add('Symfony',           __DIR__.'/framework');
 *
 *     // activate the autoloader
 *     $loader->register();
 *
 *     // to enable searching the include path (eg. for PEAR packages)
 *     $loader->setUseIncludePath(true);
 *
 * In this example, if you try to use a class in the Symfony\Component
 * namespace or one of its children (Symfony\Component\Console for instance),
 * the autoloader will first look for the class under the component/
 * directory, and it will then fallback to the framework/ directory if not
 * found before giving up.
 *
 * This class is loosely based on the Symfony UniversalClassLoader.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @see    http://www.php-fig.org/psr/psr-0/
 * @see    http://www.php-fig.org/psr/psr-4/
 */
class ClassLoader
{
    // PSR-4
    private $prefixLengthsPsr4 = array();
    private $prefixDirsPsr4 = array();
    private $fallbackDirsPsr4 = array();

    // PSR-0
    private $prefixesPsr0 = array();
    private $fallbackDirsPsr0 = array();

    private $useIncludePath = false;
    private $classMap = array();
    private $classMapAuthoritative = false;
    private $missingClasses = array();
    private $apcuPrefix;

    public function getPrefixes()
    {
        if (!empty($this->prefixesPsr0)) {
            return call_user_func_array('array_merge', $this->prefixesPsr0);
        }

        return array();
    }

    public function getPrefixesPsr4()
    {
        return $this->prefixDirsPsr4;
    }

    public function getFallbackDirs()
    {
        return $this->fallbackDirsPsr0;
    }

    public function getFallbackDirsPsr4()
    {
        return $this->fallbackDirsPsr4;
    }

    public function getClassMap()
    {
        return $this->classMap;
    }

    /**
     * @param array $classMap Class to filename map
     */
    public function addClassMap(array $classMap)
    {
        if ($this->classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix, either
     * appending or prepending to the ones previously set for this prefix.
     *
     * @param string       $prefix  The prefix
     * @param array|string $paths   The PSR-0 root directories
     * @param bool         $prepend Whether to prepend the directories
     */
    public function add($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            if ($prepend) {
                $this->fallbackDirsPsr0 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr0
                );
            } else {
                $this->fallbackDirsPsr0 = array_merge(
                    $this->fallbackDirsPsr0,
                    (array) $paths
                );
            }

            return;
        }

        $first = $prefix[0];
        if (!isset($this->prefixesPsr0[$first][$prefix])) {
            $this->prefixesPsr0[$first][$prefix] = (array) $paths;

            return;
        }
        if ($prepend) {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                (array) $paths,
                $this->prefixesPsr0[$first][$prefix]
            );
        } else {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                $this->prefixesPsr0[$first][$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace, either
     * appending or prepending to the ones previously set for this namespace.
     *
     * @param string       $prefix  The prefix/namespace, with trailing '\\'
     * @param array|string $paths   The PSR-4 base directories
     * @param bool         $prepend Whether to prepend the directories
     *
     * @throws \InvalidArgumentException
     */
    public function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                $this->fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr4
                );
            } else {
                $this->fallbackDirsPsr4 = array_merge(
                    $this->fallbackDirsPsr4,
                    (array) $paths
                );
            }
        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
            // Register directories for a new namespace.
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                $this->prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                $this->prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix,
     * replacing any others previously set for this prefix.
     *
     * @param string       $prefix The prefix
     * @param array|string $paths  The PSR-0 base directories
     */
    public function set($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr0 = (array) $paths;
        } else {
            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace,
     * replacing any others previously set for this namespace.
     *
     * @param string       $prefix The prefix/namespace, with trailing '\\'
     * @param array|string $paths  The PSR-4 base directories
     *
     * @throws \InvalidArgumentException
     */
    public function setPsr4($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

    /**
     * Turns on searching the include path for class files.
     *
     * @param bool $useIncludePath
     */
    public function setUseIncludePath($useIncludePath)
    {
        $this->useIncludePath = $useIncludePath;
    }

    /**
     * Can be used to check if the autoloader uses the include path to check
     * for classes.
     *
     * @return bool
     */
    public function getUseIncludePath()
    {
        return $this->useIncludePath;
    }

    /**
     * Turns off searching the prefix and fallback directories for classes
     * that have not been registered with the class map.
     *
     * @param bool $classMapAuthoritative
     */
    public function setClassMapAuthoritative($classMapAuthoritative)
    {
        $this->classMapAuthoritative = $classMapAuthoritative;
    }

    /**
     * Should class lookup fail if not found in the current class map?
     *
     * @return bool
     */
    public function isClassMapAuthoritative()
    {
        return $this->classMapAuthoritative;
    }

    /**
     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
     *
     * @param string|null $apcuPrefix
     */
    public function setApcuPrefix($apcuPrefix)
    {
        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
    }

    /**
     * The APCu prefix in use, or null if APCu caching is not enabled.
     *
     * @return string|null
     */
    public function getApcuPrefix()
    {
        return $this->apcuPrefix;
    }

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     */
    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
    }

    /**
     * Unregisters this instance as an autoloader.
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));
    }

    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return bool|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }
    }

    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
            return false;
        }
        if (null !== $this->apcuPrefix) {
            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
            if ($hit) {
                return $file;
            }
        }

        $file = $this->findFileWithExtension($class, '.php');

        // Search for Hack files if we are running on HHVM
        if (false === $file && defined('HHVM_VERSION')) {
            $file = $this->findFileWithExtension($class, '.hh');
        }

        if (null !== $this->apcuPrefix) {
            apcu_add($this->apcuPrefix.$class, $file);
        }

        if (false === $file) {
            // Remember that this class does not exist.
            $this->missingClasses[$class] = true;
        }

        return $file;
    }

    private function findFileWithExtension($class, $ext)
    {
        // PSR-4 lookup
        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

        $first = $class[0];
        if (isset($this->prefixLengthsPsr4[$first])) {
            $subPath = $class;
            while (false !== $lastPos = strrpos($subPath, '\\')) {
                $subPath = substr($subPath, 0, $lastPos);
                $search = $subPath . '\\';
                if (isset($this->prefixDirsPsr4[$search])) {
                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
                        if (file_exists($file = $dir . $pathEnd)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-4 fallback dirs
        foreach ($this->fallbackDirsPsr4 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                return $file;
            }
        }

        // PSR-0 lookup
        if (false !== $pos = strrpos($class, '\\')) {
            // namespaced class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
        }

        if (isset($this->prefixesPsr0[$first])) {
            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-0 fallback dirs
        foreach ($this->fallbackDirsPsr0 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                return $file;
            }
        }

        // PSR-0 include paths.
        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
            return $file;
        }

        return false;
    }
}

/**
 * Scope isolated include.
 *
 * Prevents access to $this/self from included files.
 */
function includeFile($file)
{
    include $file;
}
<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit2465bc1320a965a378e5f39bc0181113
{
    public static $files = array (
        '44f761fde233c98b53686bd6223104dd' => __DIR__ . '/../..' . '/src/pocketmine/CoreConstants.php',
        '9c3c6f7f4a17396c3ff535f7d7c38ad4' => __DIR__ . '/../..' . '/src/pocketmine/GlobalConstants.php',
        '89d5de50ff2daa656af29fba38fbd9af' => __DIR__ . '/../..' . '/src/pocketmine/VersionInfo.php',
    );

    public static $prefixLengthsPsr4 = array (
        'r' => 
        array (
            'raklib\\' => 7,
        ),
        'p' => 
        array (
            'pocketmine\\utils\\' => 17,
            'pocketmine\\snooze\\' => 18,
            'pocketmine\\nbt\\' => 15,
            'pocketmine\\math\\' => 16,
        ),
        'D' => 
        array (
            'DaveRandom\\CallbackValidator\\' => 29,
        ),
        'A' => 
        array (
            'Ahc\\Json\\' => 9,
        ),
    );

    public static $prefixDirsPsr4 = array (
        'raklib\\' => 
        array (
            0 => __DIR__ . '/..' . '/pocketmine/raklib/src',
        ),
        'pocketmine\\utils\\' => 
        array (
            0 => __DIR__ . '/..' . '/pocketmine/binaryutils/src',
        ),
        'pocketmine\\snooze\\' => 
        array (
            0 => __DIR__ . '/..' . '/pocketmine/snooze/src',
        ),
        'pocketmine\\nbt\\' => 
        array (
            0 => __DIR__ . '/..' . '/pocketmine/nbt/src',
        ),
        'pocketmine\\math\\' => 
        array (
            0 => __DIR__ . '/..' . '/pocketmine/math/src',
        ),
        'DaveRandom\\CallbackValidator\\' => 
        array (
            0 => __DIR__ . '/..' . '/daverandom/callback-validator/src',
        ),
        'Ahc\\Json\\' => 
        array (
            0 => __DIR__ . '/..' . '/adhocore/json-comment/src',
        ),
    );

    public static $fallbackDirsPsr4 = array (
        0 => __DIR__ . '/../..' . '/src',
    );

    public static $classMap = array (
        'Ahc\\Json\\Comment' => __DIR__ . '/..' . '/adhocore/json-comment/src/Comment.php',
        'ArrayOutOfBoundsException' => __DIR__ . '/..' . '/pocketmine/spl/src/ArrayOutOfBoundsException.php',
        'AttachableLogger' => __DIR__ . '/..' . '/pocketmine/log/src/AttachableLogger.php',
        'AttachableThreadedLogger' => __DIR__ . '/..' . '/pocketmine/log/src/AttachableThreadedLogger.php',
        'BaseClassLoader' => __DIR__ . '/..' . '/pocketmine/classloader/src/BaseClassLoader.php',
        'ClassCastException' => __DIR__ . '/..' . '/pocketmine/spl/src/ClassCastException.php',
        'ClassLoader' => __DIR__ . '/..' . '/pocketmine/classloader/src/ClassLoader.php',
        'ClassNotFoundException' => __DIR__ . '/..' . '/pocketmine/spl/src/ClassNotFoundException.php',
        'DaveRandom\\CallbackValidator\\BuiltInTypes' => __DIR__ . '/..' . '/daverandom/callback-validator/src/BuiltInTypes.php',
        'DaveRandom\\CallbackValidator\\CallbackType' => __DIR__ . '/..' . '/daverandom/callback-validator/src/CallbackType.php',
        'DaveRandom\\CallbackValidator\\InvalidCallbackException' => __DIR__ . '/..' . '/daverandom/callback-validator/src/InvalidCallbackException.php',
        'DaveRandom\\CallbackValidator\\MatchTester' => __DIR__ . '/..' . '/daverandom/callback-validator/src/MatchTester.php',
        'DaveRandom\\CallbackValidator\\ParameterType' => __DIR__ . '/..' . '/daverandom/callback-validator/src/ParameterType.php',
        'DaveRandom\\CallbackValidator\\ReturnType' => __DIR__ . '/..' . '/daverandom/callback-validator/src/ReturnType.php',
        'DaveRandom\\CallbackValidator\\Type' => __DIR__ . '/..' . '/daverandom/callback-validator/src/Type.php',
        'InvalidArgumentCountException' => __DIR__ . '/..' . '/pocketmine/spl/src/InvalidArgumentCountException.php',
        'InvalidKeyException' => __DIR__ . '/..' . '/pocketmine/spl/src/InvalidKeyException.php',
        'InvalidStateException' => __DIR__ . '/..' . '/pocketmine/spl/src/InvalidStateException.php',
        'LogLevel' => __DIR__ . '/..' . '/pocketmine/log/src/LogLevel.php',
        'Logger' => __DIR__ . '/..' . '/pocketmine/log/src/Logger.php',
        'LoggerAttachment' => __DIR__ . '/..' . '/pocketmine/log/src/LoggerAttachment.php',
        'SplFixedByteArray' => __DIR__ . '/..' . '/pocketmine/spl/src/SplFixedByteArray.php',
        'StringOutOfBoundsException' => __DIR__ . '/..' . '/pocketmine/spl/src/StringOutOfBoundsException.php',
        'ThreadException' => __DIR__ . '/..' . '/pocketmine/spl/src/ThreadException.php',
        'ThreadedLogger' => __DIR__ . '/..' . '/pocketmine/log/src/ThreadedLogger.php',
        'ThreadedLoggerAttachment' => __DIR__ . '/..' . '/pocketmine/log/src/ThreadedLoggerAttachment.php',
        'UndefinedConstantException' => __DIR__ . '/..' . '/pocketmine/spl/src/UndefinedConstantException.php',
        'UndefinedPropertyException' => __DIR__ . '/..' . '/pocketmine/spl/src/UndefinedPropertyException.php',
        'UndefinedVariableException' => __DIR__ . '/..' . '/pocketmine/spl/src/UndefinedVariableException.php',
        'pocketmine\\Achievement' => __DIR__ . '/../..' . '/src/pocketmine/Achievement.php',
        'pocketmine\\Collectable' => __DIR__ . '/../..' . '/src/pocketmine/Collectable.php',
        'pocketmine\\CrashDump' => __DIR__ . '/../..' . '/src/pocketmine/CrashDump.php',
        'pocketmine\\IPlayer' => __DIR__ . '/../..' . '/src/pocketmine/IPlayer.php',
        'pocketmine\\MemoryManager' => __DIR__ . '/../..' . '/src/pocketmine/MemoryManager.php',
        'pocketmine\\OfflinePlayer' => __DIR__ . '/../..' . '/src/pocketmine/OfflinePlayer.php',
        'pocketmine\\Player' => __DIR__ . '/../..' . '/src/pocketmine/Player.php',
        'pocketmine\\Server' => __DIR__ . '/../..' . '/src/pocketmine/Server.php',
        'pocketmine\\Thread' => __DIR__ . '/../..' . '/src/pocketmine/Thread.php',
        'pocketmine\\ThreadManager' => __DIR__ . '/../..' . '/src/pocketmine/ThreadManager.php',
        'pocketmine\\Worker' => __DIR__ . '/../..' . '/src/pocketmine/Worker.php',
        'pocketmine\\block\\ActivatorRail' => __DIR__ . '/../..' . '/src/pocketmine/block/ActivatorRail.php',
        'pocketmine\\block\\Air' => __DIR__ . '/../..' . '/src/pocketmine/block/Air.php',
        'pocketmine\\block\\Anvil' => __DIR__ . '/../..' . '/src/pocketmine/block/Anvil.php',
        'pocketmine\\block\\BaseRail' => __DIR__ . '/../..' . '/src/pocketmine/block/BaseRail.php',
        'pocketmine\\block\\Bed' => __DIR__ . '/../..' . '/src/pocketmine/block/Bed.php',
        'pocketmine\\block\\Bedrock' => __DIR__ . '/../..' . '/src/pocketmine/block/Bedrock.php',
        'pocketmine\\block\\Beetroot' => __DIR__ . '/../..' . '/src/pocketmine/block/Beetroot.php',
        'pocketmine\\block\\Block' => __DIR__ . '/../..' . '/src/pocketmine/block/Block.php',
        'pocketmine\\block\\BlockFactory' => __DIR__ . '/../..' . '/src/pocketmine/block/BlockFactory.php',
        'pocketmine\\block\\BlockIds' => __DIR__ . '/../..' . '/src/pocketmine/block/BlockIds.php',
        'pocketmine\\block\\BlockToolType' => __DIR__ . '/../..' . '/src/pocketmine/block/BlockToolType.php',
        'pocketmine\\block\\BoneBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/BoneBlock.php',
        'pocketmine\\block\\Bookshelf' => __DIR__ . '/../..' . '/src/pocketmine/block/Bookshelf.php',
        'pocketmine\\block\\BrewingStand' => __DIR__ . '/../..' . '/src/pocketmine/block/BrewingStand.php',
        'pocketmine\\block\\BrickStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/BrickStairs.php',
        'pocketmine\\block\\Bricks' => __DIR__ . '/../..' . '/src/pocketmine/block/Bricks.php',
        'pocketmine\\block\\BrownMushroom' => __DIR__ . '/../..' . '/src/pocketmine/block/BrownMushroom.php',
        'pocketmine\\block\\BrownMushroomBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/BrownMushroomBlock.php',
        'pocketmine\\block\\BurningFurnace' => __DIR__ . '/../..' . '/src/pocketmine/block/BurningFurnace.php',
        'pocketmine\\block\\Button' => __DIR__ . '/../..' . '/src/pocketmine/block/Button.php',
        'pocketmine\\block\\Cactus' => __DIR__ . '/../..' . '/src/pocketmine/block/Cactus.php',
        'pocketmine\\block\\Cake' => __DIR__ . '/../..' . '/src/pocketmine/block/Cake.php',
        'pocketmine\\block\\Carpet' => __DIR__ . '/../..' . '/src/pocketmine/block/Carpet.php',
        'pocketmine\\block\\Carrot' => __DIR__ . '/../..' . '/src/pocketmine/block/Carrot.php',
        'pocketmine\\block\\Chest' => __DIR__ . '/../..' . '/src/pocketmine/block/Chest.php',
        'pocketmine\\block\\Clay' => __DIR__ . '/../..' . '/src/pocketmine/block/Clay.php',
        'pocketmine\\block\\Coal' => __DIR__ . '/../..' . '/src/pocketmine/block/Coal.php',
        'pocketmine\\block\\CoalOre' => __DIR__ . '/../..' . '/src/pocketmine/block/CoalOre.php',
        'pocketmine\\block\\Cobblestone' => __DIR__ . '/../..' . '/src/pocketmine/block/Cobblestone.php',
        'pocketmine\\block\\CobblestoneStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/CobblestoneStairs.php',
        'pocketmine\\block\\CobblestoneWall' => __DIR__ . '/../..' . '/src/pocketmine/block/CobblestoneWall.php',
        'pocketmine\\block\\Cobweb' => __DIR__ . '/../..' . '/src/pocketmine/block/Cobweb.php',
        'pocketmine\\block\\CocoaBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/CocoaBlock.php',
        'pocketmine\\block\\Concrete' => __DIR__ . '/../..' . '/src/pocketmine/block/Concrete.php',
        'pocketmine\\block\\ConcretePowder' => __DIR__ . '/../..' . '/src/pocketmine/block/ConcretePowder.php',
        'pocketmine\\block\\CraftingTable' => __DIR__ . '/../..' . '/src/pocketmine/block/CraftingTable.php',
        'pocketmine\\block\\Crops' => __DIR__ . '/../..' . '/src/pocketmine/block/Crops.php',
        'pocketmine\\block\\Dandelion' => __DIR__ . '/../..' . '/src/pocketmine/block/Dandelion.php',
        'pocketmine\\block\\DaylightSensor' => __DIR__ . '/../..' . '/src/pocketmine/block/DaylightSensor.php',
        'pocketmine\\block\\DeadBush' => __DIR__ . '/../..' . '/src/pocketmine/block/DeadBush.php',
        'pocketmine\\block\\DetectorRail' => __DIR__ . '/../..' . '/src/pocketmine/block/DetectorRail.php',
        'pocketmine\\block\\Diamond' => __DIR__ . '/../..' . '/src/pocketmine/block/Diamond.php',
        'pocketmine\\block\\DiamondOre' => __DIR__ . '/../..' . '/src/pocketmine/block/DiamondOre.php',
        'pocketmine\\block\\Dirt' => __DIR__ . '/../..' . '/src/pocketmine/block/Dirt.php',
        'pocketmine\\block\\Door' => __DIR__ . '/../..' . '/src/pocketmine/block/Door.php',
        'pocketmine\\block\\DoublePlant' => __DIR__ . '/../..' . '/src/pocketmine/block/DoublePlant.php',
        'pocketmine\\block\\DoubleSlab' => __DIR__ . '/../..' . '/src/pocketmine/block/DoubleSlab.php',
        'pocketmine\\block\\DoubleStoneSlab' => __DIR__ . '/../..' . '/src/pocketmine/block/DoubleStoneSlab.php',
        'pocketmine\\block\\DoubleStoneSlab2' => __DIR__ . '/../..' . '/src/pocketmine/block/DoubleStoneSlab2.php',
        'pocketmine\\block\\DoubleWoodenSlab' => __DIR__ . '/../..' . '/src/pocketmine/block/DoubleWoodenSlab.php',
        'pocketmine\\block\\Emerald' => __DIR__ . '/../..' . '/src/pocketmine/block/Emerald.php',
        'pocketmine\\block\\EmeraldOre' => __DIR__ . '/../..' . '/src/pocketmine/block/EmeraldOre.php',
        'pocketmine\\block\\EnchantingTable' => __DIR__ . '/../..' . '/src/pocketmine/block/EnchantingTable.php',
        'pocketmine\\block\\EndPortalFrame' => __DIR__ . '/../..' . '/src/pocketmine/block/EndPortalFrame.php',
        'pocketmine\\block\\EndRod' => __DIR__ . '/../..' . '/src/pocketmine/block/EndRod.php',
        'pocketmine\\block\\EndStone' => __DIR__ . '/../..' . '/src/pocketmine/block/EndStone.php',
        'pocketmine\\block\\EndStoneBricks' => __DIR__ . '/../..' . '/src/pocketmine/block/EndStoneBricks.php',
        'pocketmine\\block\\EnderChest' => __DIR__ . '/../..' . '/src/pocketmine/block/EnderChest.php',
        'pocketmine\\block\\Fallable' => __DIR__ . '/../..' . '/src/pocketmine/block/Fallable.php',
        'pocketmine\\block\\Farmland' => __DIR__ . '/../..' . '/src/pocketmine/block/Farmland.php',
        'pocketmine\\block\\Fence' => __DIR__ . '/../..' . '/src/pocketmine/block/Fence.php',
        'pocketmine\\block\\FenceGate' => __DIR__ . '/../..' . '/src/pocketmine/block/FenceGate.php',
        'pocketmine\\block\\Fire' => __DIR__ . '/../..' . '/src/pocketmine/block/Fire.php',
        'pocketmine\\block\\Flowable' => __DIR__ . '/../..' . '/src/pocketmine/block/Flowable.php',
        'pocketmine\\block\\Flower' => __DIR__ . '/../..' . '/src/pocketmine/block/Flower.php',
        'pocketmine\\block\\FlowerPot' => __DIR__ . '/../..' . '/src/pocketmine/block/FlowerPot.php',
        'pocketmine\\block\\Furnace' => __DIR__ . '/../..' . '/src/pocketmine/block/Furnace.php',
        'pocketmine\\block\\Glass' => __DIR__ . '/../..' . '/src/pocketmine/block/Glass.php',
        'pocketmine\\block\\GlassPane' => __DIR__ . '/../..' . '/src/pocketmine/block/GlassPane.php',
        'pocketmine\\block\\GlazedTerracotta' => __DIR__ . '/../..' . '/src/pocketmine/block/GlazedTerracotta.php',
        'pocketmine\\block\\GlowingObsidian' => __DIR__ . '/../..' . '/src/pocketmine/block/GlowingObsidian.php',
        'pocketmine\\block\\GlowingRedstoneOre' => __DIR__ . '/../..' . '/src/pocketmine/block/GlowingRedstoneOre.php',
        'pocketmine\\block\\Glowstone' => __DIR__ . '/../..' . '/src/pocketmine/block/Glowstone.php',
        'pocketmine\\block\\Gold' => __DIR__ . '/../..' . '/src/pocketmine/block/Gold.php',
        'pocketmine\\block\\GoldOre' => __DIR__ . '/../..' . '/src/pocketmine/block/GoldOre.php',
        'pocketmine\\block\\Grass' => __DIR__ . '/../..' . '/src/pocketmine/block/Grass.php',
        'pocketmine\\block\\GrassPath' => __DIR__ . '/../..' . '/src/pocketmine/block/GrassPath.php',
        'pocketmine\\block\\Gravel' => __DIR__ . '/../..' . '/src/pocketmine/block/Gravel.php',
        'pocketmine\\block\\HardenedClay' => __DIR__ . '/../..' . '/src/pocketmine/block/HardenedClay.php',
        'pocketmine\\block\\HayBale' => __DIR__ . '/../..' . '/src/pocketmine/block/HayBale.php',
        'pocketmine\\block\\Ice' => __DIR__ . '/../..' . '/src/pocketmine/block/Ice.php',
        'pocketmine\\block\\InfoUpdate' => __DIR__ . '/../..' . '/src/pocketmine/block/InfoUpdate.php',
        'pocketmine\\block\\InvisibleBedrock' => __DIR__ . '/../..' . '/src/pocketmine/block/InvisibleBedrock.php',
        'pocketmine\\block\\Iron' => __DIR__ . '/../..' . '/src/pocketmine/block/Iron.php',
        'pocketmine\\block\\IronBars' => __DIR__ . '/../..' . '/src/pocketmine/block/IronBars.php',
        'pocketmine\\block\\IronDoor' => __DIR__ . '/../..' . '/src/pocketmine/block/IronDoor.php',
        'pocketmine\\block\\IronOre' => __DIR__ . '/../..' . '/src/pocketmine/block/IronOre.php',
        'pocketmine\\block\\IronTrapdoor' => __DIR__ . '/../..' . '/src/pocketmine/block/IronTrapdoor.php',
        'pocketmine\\block\\ItemFrame' => __DIR__ . '/../..' . '/src/pocketmine/block/ItemFrame.php',
        'pocketmine\\block\\Ladder' => __DIR__ . '/../..' . '/src/pocketmine/block/Ladder.php',
        'pocketmine\\block\\Lapis' => __DIR__ . '/../..' . '/src/pocketmine/block/Lapis.php',
        'pocketmine\\block\\LapisOre' => __DIR__ . '/../..' . '/src/pocketmine/block/LapisOre.php',
        'pocketmine\\block\\Lava' => __DIR__ . '/../..' . '/src/pocketmine/block/Lava.php',
        'pocketmine\\block\\Leaves' => __DIR__ . '/../..' . '/src/pocketmine/block/Leaves.php',
        'pocketmine\\block\\Leaves2' => __DIR__ . '/../..' . '/src/pocketmine/block/Leaves2.php',
        'pocketmine\\block\\Lever' => __DIR__ . '/../..' . '/src/pocketmine/block/Lever.php',
        'pocketmine\\block\\Liquid' => __DIR__ . '/../..' . '/src/pocketmine/block/Liquid.php',
        'pocketmine\\block\\LitPumpkin' => __DIR__ . '/../..' . '/src/pocketmine/block/LitPumpkin.php',
        'pocketmine\\block\\LitRedstoneLamp' => __DIR__ . '/../..' . '/src/pocketmine/block/LitRedstoneLamp.php',
        'pocketmine\\block\\Magma' => __DIR__ . '/../..' . '/src/pocketmine/block/Magma.php',
        'pocketmine\\block\\Melon' => __DIR__ . '/../..' . '/src/pocketmine/block/Melon.php',
        'pocketmine\\block\\MelonStem' => __DIR__ . '/../..' . '/src/pocketmine/block/MelonStem.php',
        'pocketmine\\block\\MonsterSpawner' => __DIR__ . '/../..' . '/src/pocketmine/block/MonsterSpawner.php',
        'pocketmine\\block\\MossyCobblestone' => __DIR__ . '/../..' . '/src/pocketmine/block/MossyCobblestone.php',
        'pocketmine\\block\\Mycelium' => __DIR__ . '/../..' . '/src/pocketmine/block/Mycelium.php',
        'pocketmine\\block\\NetherBrick' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherBrick.php',
        'pocketmine\\block\\NetherBrickFence' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherBrickFence.php',
        'pocketmine\\block\\NetherBrickStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherBrickStairs.php',
        'pocketmine\\block\\NetherQuartzOre' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherQuartzOre.php',
        'pocketmine\\block\\NetherReactor' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherReactor.php',
        'pocketmine\\block\\NetherWartBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherWartBlock.php',
        'pocketmine\\block\\NetherWartPlant' => __DIR__ . '/../..' . '/src/pocketmine/block/NetherWartPlant.php',
        'pocketmine\\block\\Netherrack' => __DIR__ . '/../..' . '/src/pocketmine/block/Netherrack.php',
        'pocketmine\\block\\NoteBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/NoteBlock.php',
        'pocketmine\\block\\Obsidian' => __DIR__ . '/../..' . '/src/pocketmine/block/Obsidian.php',
        'pocketmine\\block\\PackedIce' => __DIR__ . '/../..' . '/src/pocketmine/block/PackedIce.php',
        'pocketmine\\block\\Planks' => __DIR__ . '/../..' . '/src/pocketmine/block/Planks.php',
        'pocketmine\\block\\Podzol' => __DIR__ . '/../..' . '/src/pocketmine/block/Podzol.php',
        'pocketmine\\block\\Potato' => __DIR__ . '/../..' . '/src/pocketmine/block/Potato.php',
        'pocketmine\\block\\PoweredRail' => __DIR__ . '/../..' . '/src/pocketmine/block/PoweredRail.php',
        'pocketmine\\block\\Prismarine' => __DIR__ . '/../..' . '/src/pocketmine/block/Prismarine.php',
        'pocketmine\\block\\Pumpkin' => __DIR__ . '/../..' . '/src/pocketmine/block/Pumpkin.php',
        'pocketmine\\block\\PumpkinStem' => __DIR__ . '/../..' . '/src/pocketmine/block/PumpkinStem.php',
        'pocketmine\\block\\Purpur' => __DIR__ . '/../..' . '/src/pocketmine/block/Purpur.php',
        'pocketmine\\block\\PurpurStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/PurpurStairs.php',
        'pocketmine\\block\\Quartz' => __DIR__ . '/../..' . '/src/pocketmine/block/Quartz.php',
        'pocketmine\\block\\QuartzStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/QuartzStairs.php',
        'pocketmine\\block\\Rail' => __DIR__ . '/../..' . '/src/pocketmine/block/Rail.php',
        'pocketmine\\block\\RedMushroom' => __DIR__ . '/../..' . '/src/pocketmine/block/RedMushroom.php',
        'pocketmine\\block\\RedMushroomBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/RedMushroomBlock.php',
        'pocketmine\\block\\RedSandstone' => __DIR__ . '/../..' . '/src/pocketmine/block/RedSandstone.php',
        'pocketmine\\block\\RedSandstoneStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/RedSandstoneStairs.php',
        'pocketmine\\block\\Redstone' => __DIR__ . '/../..' . '/src/pocketmine/block/Redstone.php',
        'pocketmine\\block\\RedstoneLamp' => __DIR__ . '/../..' . '/src/pocketmine/block/RedstoneLamp.php',
        'pocketmine\\block\\RedstoneOre' => __DIR__ . '/../..' . '/src/pocketmine/block/RedstoneOre.php',
        'pocketmine\\block\\RedstoneRail' => __DIR__ . '/../..' . '/src/pocketmine/block/RedstoneRail.php',
        'pocketmine\\block\\RedstoneTorch' => __DIR__ . '/../..' . '/src/pocketmine/block/RedstoneTorch.php',
        'pocketmine\\block\\RedstoneTorchUnlit' => __DIR__ . '/../..' . '/src/pocketmine/block/RedstoneTorchUnlit.php',
        'pocketmine\\block\\Reserved6' => __DIR__ . '/../..' . '/src/pocketmine/block/Reserved6.php',
        'pocketmine\\block\\Sand' => __DIR__ . '/../..' . '/src/pocketmine/block/Sand.php',
        'pocketmine\\block\\Sandstone' => __DIR__ . '/../..' . '/src/pocketmine/block/Sandstone.php',
        'pocketmine\\block\\SandstoneStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/SandstoneStairs.php',
        'pocketmine\\block\\Sapling' => __DIR__ . '/../..' . '/src/pocketmine/block/Sapling.php',
        'pocketmine\\block\\SeaLantern' => __DIR__ . '/../..' . '/src/pocketmine/block/SeaLantern.php',
        'pocketmine\\block\\SignPost' => __DIR__ . '/../..' . '/src/pocketmine/block/SignPost.php',
        'pocketmine\\block\\Skull' => __DIR__ . '/../..' . '/src/pocketmine/block/Skull.php',
        'pocketmine\\block\\Slab' => __DIR__ . '/../..' . '/src/pocketmine/block/Slab.php',
        'pocketmine\\block\\Snow' => __DIR__ . '/../..' . '/src/pocketmine/block/Snow.php',
        'pocketmine\\block\\SnowLayer' => __DIR__ . '/../..' . '/src/pocketmine/block/SnowLayer.php',
        'pocketmine\\block\\Solid' => __DIR__ . '/../..' . '/src/pocketmine/block/Solid.php',
        'pocketmine\\block\\SoulSand' => __DIR__ . '/../..' . '/src/pocketmine/block/SoulSand.php',
        'pocketmine\\block\\Sponge' => __DIR__ . '/../..' . '/src/pocketmine/block/Sponge.php',
        'pocketmine\\block\\StainedClay' => __DIR__ . '/../..' . '/src/pocketmine/block/StainedClay.php',
        'pocketmine\\block\\StainedGlass' => __DIR__ . '/../..' . '/src/pocketmine/block/StainedGlass.php',
        'pocketmine\\block\\StainedGlassPane' => __DIR__ . '/../..' . '/src/pocketmine/block/StainedGlassPane.php',
        'pocketmine\\block\\Stair' => __DIR__ . '/../..' . '/src/pocketmine/block/Stair.php',
        'pocketmine\\block\\StandingBanner' => __DIR__ . '/../..' . '/src/pocketmine/block/StandingBanner.php',
        'pocketmine\\block\\StillLava' => __DIR__ . '/../..' . '/src/pocketmine/block/StillLava.php',
        'pocketmine\\block\\StillWater' => __DIR__ . '/../..' . '/src/pocketmine/block/StillWater.php',
        'pocketmine\\block\\Stone' => __DIR__ . '/../..' . '/src/pocketmine/block/Stone.php',
        'pocketmine\\block\\StoneBrickStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/StoneBrickStairs.php',
        'pocketmine\\block\\StoneBricks' => __DIR__ . '/../..' . '/src/pocketmine/block/StoneBricks.php',
        'pocketmine\\block\\StoneButton' => __DIR__ . '/../..' . '/src/pocketmine/block/StoneButton.php',
        'pocketmine\\block\\StonePressurePlate' => __DIR__ . '/../..' . '/src/pocketmine/block/StonePressurePlate.php',
        'pocketmine\\block\\StoneSlab' => __DIR__ . '/../..' . '/src/pocketmine/block/StoneSlab.php',
        'pocketmine\\block\\StoneSlab2' => __DIR__ . '/../..' . '/src/pocketmine/block/StoneSlab2.php',
        'pocketmine\\block\\Stonecutter' => __DIR__ . '/../..' . '/src/pocketmine/block/Stonecutter.php',
        'pocketmine\\block\\Sugarcane' => __DIR__ . '/../..' . '/src/pocketmine/block/Sugarcane.php',
        'pocketmine\\block\\TNT' => __DIR__ . '/../..' . '/src/pocketmine/block/TNT.php',
        'pocketmine\\block\\TallGrass' => __DIR__ . '/../..' . '/src/pocketmine/block/TallGrass.php',
        'pocketmine\\block\\Thin' => __DIR__ . '/../..' . '/src/pocketmine/block/Thin.php',
        'pocketmine\\block\\Torch' => __DIR__ . '/../..' . '/src/pocketmine/block/Torch.php',
        'pocketmine\\block\\Transparent' => __DIR__ . '/../..' . '/src/pocketmine/block/Transparent.php',
        'pocketmine\\block\\Trapdoor' => __DIR__ . '/../..' . '/src/pocketmine/block/Trapdoor.php',
        'pocketmine\\block\\TrappedChest' => __DIR__ . '/../..' . '/src/pocketmine/block/TrappedChest.php',
        'pocketmine\\block\\Tripwire' => __DIR__ . '/../..' . '/src/pocketmine/block/Tripwire.php',
        'pocketmine\\block\\TripwireHook' => __DIR__ . '/../..' . '/src/pocketmine/block/TripwireHook.php',
        'pocketmine\\block\\UnknownBlock' => __DIR__ . '/../..' . '/src/pocketmine/block/UnknownBlock.php',
        'pocketmine\\block\\Vine' => __DIR__ . '/../..' . '/src/pocketmine/block/Vine.php',
        'pocketmine\\block\\WallBanner' => __DIR__ . '/../..' . '/src/pocketmine/block/WallBanner.php',
        'pocketmine\\block\\WallSign' => __DIR__ . '/../..' . '/src/pocketmine/block/WallSign.php',
        'pocketmine\\block\\Water' => __DIR__ . '/../..' . '/src/pocketmine/block/Water.php',
        'pocketmine\\block\\WaterLily' => __DIR__ . '/../..' . '/src/pocketmine/block/WaterLily.php',
        'pocketmine\\block\\WeightedPressurePlateHeavy' => __DIR__ . '/../..' . '/src/pocketmine/block/WeightedPressurePlateHeavy.php',
        'pocketmine\\block\\WeightedPressurePlateLight' => __DIR__ . '/../..' . '/src/pocketmine/block/WeightedPressurePlateLight.php',
        'pocketmine\\block\\Wheat' => __DIR__ . '/../..' . '/src/pocketmine/block/Wheat.php',
        'pocketmine\\block\\Wood' => __DIR__ . '/../..' . '/src/pocketmine/block/Wood.php',
        'pocketmine\\block\\Wood2' => __DIR__ . '/../..' . '/src/pocketmine/block/Wood2.php',
        'pocketmine\\block\\WoodenButton' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenButton.php',
        'pocketmine\\block\\WoodenDoor' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenDoor.php',
        'pocketmine\\block\\WoodenFence' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenFence.php',
        'pocketmine\\block\\WoodenPressurePlate' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenPressurePlate.php',
        'pocketmine\\block\\WoodenSlab' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenSlab.php',
        'pocketmine\\block\\WoodenStairs' => __DIR__ . '/../..' . '/src/pocketmine/block/WoodenStairs.php',
        'pocketmine\\block\\Wool' => __DIR__ . '/../..' . '/src/pocketmine/block/Wool.php',
        'pocketmine\\block\\utils\\ColorBlockMetaHelper' => __DIR__ . '/../..' . '/src/pocketmine/block/utils/ColorBlockMetaHelper.php',
        'pocketmine\\block\\utils\\PillarRotationHelper' => __DIR__ . '/../..' . '/src/pocketmine/block/utils/PillarRotationHelper.php',
        'pocketmine\\command\\Command' => __DIR__ . '/../..' . '/src/pocketmine/command/Command.php',
        'pocketmine\\command\\CommandExecutor' => __DIR__ . '/../..' . '/src/pocketmine/command/CommandExecutor.php',
        'pocketmine\\command\\CommandMap' => __DIR__ . '/../..' . '/src/pocketmine/command/CommandMap.php',
        'pocketmine\\command\\CommandReader' => __DIR__ . '/../..' . '/src/pocketmine/command/CommandReader.php',
        'pocketmine\\command\\CommandSender' => __DIR__ . '/../..' . '/src/pocketmine/command/CommandSender.php',
        'pocketmine\\command\\ConsoleCommandSender' => __DIR__ . '/../..' . '/src/pocketmine/command/ConsoleCommandSender.php',
        'pocketmine\\command\\FormattedCommandAlias' => __DIR__ . '/../..' . '/src/pocketmine/command/FormattedCommandAlias.php',
        'pocketmine\\command\\PluginCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/PluginCommand.php',
        'pocketmine\\command\\PluginIdentifiableCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/PluginIdentifiableCommand.php',
        'pocketmine\\command\\RemoteConsoleCommandSender' => __DIR__ . '/../..' . '/src/pocketmine/command/RemoteConsoleCommandSender.php',
        'pocketmine\\command\\SimpleCommandMap' => __DIR__ . '/../..' . '/src/pocketmine/command/SimpleCommandMap.php',
        'pocketmine\\command\\defaults\\BanCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/BanCommand.php',
        'pocketmine\\command\\defaults\\BanIpCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/BanIpCommand.php',
        'pocketmine\\command\\defaults\\BanListCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/BanListCommand.php',
        'pocketmine\\command\\defaults\\DefaultGamemodeCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/DefaultGamemodeCommand.php',
        'pocketmine\\command\\defaults\\DeopCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/DeopCommand.php',
        'pocketmine\\command\\defaults\\DifficultyCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/DifficultyCommand.php',
        'pocketmine\\command\\defaults\\DumpMemoryCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/DumpMemoryCommand.php',
        'pocketmine\\command\\defaults\\EffectCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/EffectCommand.php',
        'pocketmine\\command\\defaults\\EnchantCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/EnchantCommand.php',
        'pocketmine\\command\\defaults\\GamemodeCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/GamemodeCommand.php',
        'pocketmine\\command\\defaults\\GarbageCollectorCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/GarbageCollectorCommand.php',
        'pocketmine\\command\\defaults\\GiveCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/GiveCommand.php',
        'pocketmine\\command\\defaults\\HelpCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/HelpCommand.php',
        'pocketmine\\command\\defaults\\KickCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/KickCommand.php',
        'pocketmine\\command\\defaults\\KillCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/KillCommand.php',
        'pocketmine\\command\\defaults\\ListCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/ListCommand.php',
        'pocketmine\\command\\defaults\\MeCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/MeCommand.php',
        'pocketmine\\command\\defaults\\OpCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/OpCommand.php',
        'pocketmine\\command\\defaults\\PardonCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/PardonCommand.php',
        'pocketmine\\command\\defaults\\PardonIpCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/PardonIpCommand.php',
        'pocketmine\\command\\defaults\\ParticleCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/ParticleCommand.php',
        'pocketmine\\command\\defaults\\PluginsCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/PluginsCommand.php',
        'pocketmine\\command\\defaults\\ReloadCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/ReloadCommand.php',
        'pocketmine\\command\\defaults\\SaveCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SaveCommand.php',
        'pocketmine\\command\\defaults\\SaveOffCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SaveOffCommand.php',
        'pocketmine\\command\\defaults\\SaveOnCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SaveOnCommand.php',
        'pocketmine\\command\\defaults\\SayCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SayCommand.php',
        'pocketmine\\command\\defaults\\SeedCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SeedCommand.php',
        'pocketmine\\command\\defaults\\SetWorldSpawnCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SetWorldSpawnCommand.php',
        'pocketmine\\command\\defaults\\SpawnpointCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/SpawnpointCommand.php',
        'pocketmine\\command\\defaults\\StatusCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/StatusCommand.php',
        'pocketmine\\command\\defaults\\StopCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/StopCommand.php',
        'pocketmine\\command\\defaults\\TeleportCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TeleportCommand.php',
        'pocketmine\\command\\defaults\\TellCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TellCommand.php',
        'pocketmine\\command\\defaults\\TimeCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TimeCommand.php',
        'pocketmine\\command\\defaults\\TimingsCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TimingsCommand.php',
        'pocketmine\\command\\defaults\\TitleCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TitleCommand.php',
        'pocketmine\\command\\defaults\\TransferServerCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/TransferServerCommand.php',
        'pocketmine\\command\\defaults\\VanillaCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/VanillaCommand.php',
        'pocketmine\\command\\defaults\\VersionCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/VersionCommand.php',
        'pocketmine\\command\\defaults\\WhitelistCommand' => __DIR__ . '/../..' . '/src/pocketmine/command/defaults/WhitelistCommand.php',
        'pocketmine\\command\\utils\\CommandException' => __DIR__ . '/../..' . '/src/pocketmine/command/utils/CommandException.php',
        'pocketmine\\command\\utils\\InvalidCommandSyntaxException' => __DIR__ . '/../..' . '/src/pocketmine/command/utils/InvalidCommandSyntaxException.php',
        'pocketmine\\entity\\Ageable' => __DIR__ . '/../..' . '/src/pocketmine/entity/Ageable.php',
        'pocketmine\\entity\\Animal' => __DIR__ . '/../..' . '/src/pocketmine/entity/Animal.php',
        'pocketmine\\entity\\Attribute' => __DIR__ . '/../..' . '/src/pocketmine/entity/Attribute.php',
        'pocketmine\\entity\\AttributeMap' => __DIR__ . '/../..' . '/src/pocketmine/entity/AttributeMap.php',
        'pocketmine\\entity\\Creature' => __DIR__ . '/../..' . '/src/pocketmine/entity/Creature.php',
        'pocketmine\\entity\\Damageable' => __DIR__ . '/../..' . '/src/pocketmine/entity/Damageable.php',
        'pocketmine\\entity\\DataPropertyManager' => __DIR__ . '/../..' . '/src/pocketmine/entity/DataPropertyManager.php',
        'pocketmine\\entity\\Effect' => __DIR__ . '/../..' . '/src/pocketmine/entity/Effect.php',
        'pocketmine\\entity\\EffectInstance' => __DIR__ . '/../..' . '/src/pocketmine/entity/EffectInstance.php',
        'pocketmine\\entity\\Entity' => __DIR__ . '/../..' . '/src/pocketmine/entity/Entity.php',
        'pocketmine\\entity\\EntityIds' => __DIR__ . '/../..' . '/src/pocketmine/entity/EntityIds.php',
        'pocketmine\\entity\\Explosive' => __DIR__ . '/../..' . '/src/pocketmine/entity/Explosive.php',
        'pocketmine\\entity\\Human' => __DIR__ . '/../..' . '/src/pocketmine/entity/Human.php',
        'pocketmine\\entity\\Living' => __DIR__ . '/../..' . '/src/pocketmine/entity/Living.php',
        'pocketmine\\entity\\Monster' => __DIR__ . '/../..' . '/src/pocketmine/entity/Monster.php',
        'pocketmine\\entity\\NPC' => __DIR__ . '/../..' . '/src/pocketmine/entity/NPC.php',
        'pocketmine\\entity\\Rideable' => __DIR__ . '/../..' . '/src/pocketmine/entity/Rideable.php',
        'pocketmine\\entity\\Skin' => __DIR__ . '/../..' . '/src/pocketmine/entity/Skin.php',
        'pocketmine\\entity\\Squid' => __DIR__ . '/../..' . '/src/pocketmine/entity/Squid.php',
        'pocketmine\\entity\\Vehicle' => __DIR__ . '/../..' . '/src/pocketmine/entity/Vehicle.php',
        'pocketmine\\entity\\Villager' => __DIR__ . '/../..' . '/src/pocketmine/entity/Villager.php',
        'pocketmine\\entity\\WaterAnimal' => __DIR__ . '/../..' . '/src/pocketmine/entity/WaterAnimal.php',
        'pocketmine\\entity\\Zombie' => __DIR__ . '/../..' . '/src/pocketmine/entity/Zombie.php',
        'pocketmine\\entity\\object\\ExperienceOrb' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/ExperienceOrb.php',
        'pocketmine\\entity\\object\\FallingBlock' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/FallingBlock.php',
        'pocketmine\\entity\\object\\ItemEntity' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/ItemEntity.php',
        'pocketmine\\entity\\object\\Painting' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/Painting.php',
        'pocketmine\\entity\\object\\PaintingMotive' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/PaintingMotive.php',
        'pocketmine\\entity\\object\\PrimedTNT' => __DIR__ . '/../..' . '/src/pocketmine/entity/object/PrimedTNT.php',
        'pocketmine\\entity\\projectile\\Arrow' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/Arrow.php',
        'pocketmine\\entity\\projectile\\Egg' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/Egg.php',
        'pocketmine\\entity\\projectile\\EnderPearl' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/EnderPearl.php',
        'pocketmine\\entity\\projectile\\ExperienceBottle' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/ExperienceBottle.php',
        'pocketmine\\entity\\projectile\\Projectile' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/Projectile.php',
        'pocketmine\\entity\\projectile\\ProjectileSource' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/ProjectileSource.php',
        'pocketmine\\entity\\projectile\\Snowball' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/Snowball.php',
        'pocketmine\\entity\\projectile\\SplashPotion' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/SplashPotion.php',
        'pocketmine\\entity\\projectile\\Throwable' => __DIR__ . '/../..' . '/src/pocketmine/entity/projectile/Throwable.php',
        'pocketmine\\entity\\utils\\ExperienceUtils' => __DIR__ . '/../..' . '/src/pocketmine/entity/utils/ExperienceUtils.php',
        'pocketmine\\event\\Cancellable' => __DIR__ . '/../..' . '/src/pocketmine/event/Cancellable.php',
        'pocketmine\\event\\Event' => __DIR__ . '/../..' . '/src/pocketmine/event/Event.php',
        'pocketmine\\event\\EventPriority' => __DIR__ . '/../..' . '/src/pocketmine/event/EventPriority.php',
        'pocketmine\\event\\HandlerList' => __DIR__ . '/../..' . '/src/pocketmine/event/HandlerList.php',
        'pocketmine\\event\\Listener' => __DIR__ . '/../..' . '/src/pocketmine/event/Listener.php',
        'pocketmine\\event\\block\\BlockBreakEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockBreakEvent.php',
        'pocketmine\\event\\block\\BlockBurnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockBurnEvent.php',
        'pocketmine\\event\\block\\BlockEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockEvent.php',
        'pocketmine\\event\\block\\BlockFormEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockFormEvent.php',
        'pocketmine\\event\\block\\BlockGrowEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockGrowEvent.php',
        'pocketmine\\event\\block\\BlockPlaceEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockPlaceEvent.php',
        'pocketmine\\event\\block\\BlockSpreadEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockSpreadEvent.php',
        'pocketmine\\event\\block\\BlockUpdateEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/BlockUpdateEvent.php',
        'pocketmine\\event\\block\\LeavesDecayEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/LeavesDecayEvent.php',
        'pocketmine\\event\\block\\SignChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/block/SignChangeEvent.php',
        'pocketmine\\event\\entity\\EntityArmorChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityArmorChangeEvent.php',
        'pocketmine\\event\\entity\\EntityBlockChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityBlockChangeEvent.php',
        'pocketmine\\event\\entity\\EntityCombustByBlockEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityCombustByBlockEvent.php',
        'pocketmine\\event\\entity\\EntityCombustByEntityEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityCombustByEntityEvent.php',
        'pocketmine\\event\\entity\\EntityCombustEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityCombustEvent.php',
        'pocketmine\\event\\entity\\EntityDamageByBlockEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDamageByBlockEvent.php',
        'pocketmine\\event\\entity\\EntityDamageByChildEntityEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php',
        'pocketmine\\event\\entity\\EntityDamageByEntityEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDamageByEntityEvent.php',
        'pocketmine\\event\\entity\\EntityDamageEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDamageEvent.php',
        'pocketmine\\event\\entity\\EntityDeathEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDeathEvent.php',
        'pocketmine\\event\\entity\\EntityDespawnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityDespawnEvent.php',
        'pocketmine\\event\\entity\\EntityEffectAddEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityEffectAddEvent.php',
        'pocketmine\\event\\entity\\EntityEffectEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityEffectEvent.php',
        'pocketmine\\event\\entity\\EntityEffectRemoveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityEffectRemoveEvent.php',
        'pocketmine\\event\\entity\\EntityEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityEvent.php',
        'pocketmine\\event\\entity\\EntityExplodeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityExplodeEvent.php',
        'pocketmine\\event\\entity\\EntityInventoryChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityInventoryChangeEvent.php',
        'pocketmine\\event\\entity\\EntityLevelChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityLevelChangeEvent.php',
        'pocketmine\\event\\entity\\EntityMotionEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityMotionEvent.php',
        'pocketmine\\event\\entity\\EntityRegainHealthEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityRegainHealthEvent.php',
        'pocketmine\\event\\entity\\EntityShootBowEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityShootBowEvent.php',
        'pocketmine\\event\\entity\\EntitySpawnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntitySpawnEvent.php',
        'pocketmine\\event\\entity\\EntityTeleportEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/EntityTeleportEvent.php',
        'pocketmine\\event\\entity\\ExplosionPrimeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ExplosionPrimeEvent.php',
        'pocketmine\\event\\entity\\ItemDespawnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ItemDespawnEvent.php',
        'pocketmine\\event\\entity\\ItemSpawnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ItemSpawnEvent.php',
        'pocketmine\\event\\entity\\ProjectileHitBlockEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ProjectileHitBlockEvent.php',
        'pocketmine\\event\\entity\\ProjectileHitEntityEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ProjectileHitEntityEvent.php',
        'pocketmine\\event\\entity\\ProjectileHitEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ProjectileHitEvent.php',
        'pocketmine\\event\\entity\\ProjectileLaunchEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/entity/ProjectileLaunchEvent.php',
        'pocketmine\\event\\inventory\\CraftItemEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/CraftItemEvent.php',
        'pocketmine\\event\\inventory\\FurnaceBurnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/FurnaceBurnEvent.php',
        'pocketmine\\event\\inventory\\FurnaceSmeltEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/FurnaceSmeltEvent.php',
        'pocketmine\\event\\inventory\\InventoryCloseEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryCloseEvent.php',
        'pocketmine\\event\\inventory\\InventoryEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryEvent.php',
        'pocketmine\\event\\inventory\\InventoryOpenEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryOpenEvent.php',
        'pocketmine\\event\\inventory\\InventoryPickupArrowEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php',
        'pocketmine\\event\\inventory\\InventoryPickupItemEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryPickupItemEvent.php',
        'pocketmine\\event\\inventory\\InventoryTransactionEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/inventory/InventoryTransactionEvent.php',
        'pocketmine\\event\\level\\ChunkEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/ChunkEvent.php',
        'pocketmine\\event\\level\\ChunkLoadEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/ChunkLoadEvent.php',
        'pocketmine\\event\\level\\ChunkPopulateEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/ChunkPopulateEvent.php',
        'pocketmine\\event\\level\\ChunkUnloadEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/ChunkUnloadEvent.php',
        'pocketmine\\event\\level\\LevelEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/LevelEvent.php',
        'pocketmine\\event\\level\\LevelInitEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/LevelInitEvent.php',
        'pocketmine\\event\\level\\LevelLoadEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/LevelLoadEvent.php',
        'pocketmine\\event\\level\\LevelSaveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/LevelSaveEvent.php',
        'pocketmine\\event\\level\\LevelUnloadEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/LevelUnloadEvent.php',
        'pocketmine\\event\\level\\SpawnChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/level/SpawnChangeEvent.php',
        'pocketmine\\event\\player\\PlayerAchievementAwardedEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php',
        'pocketmine\\event\\player\\PlayerAnimationEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerAnimationEvent.php',
        'pocketmine\\event\\player\\PlayerBedEnterEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBedEnterEvent.php',
        'pocketmine\\event\\player\\PlayerBedLeaveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBedLeaveEvent.php',
        'pocketmine\\event\\player\\PlayerBlockPickEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBlockPickEvent.php',
        'pocketmine\\event\\player\\PlayerBucketEmptyEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBucketEmptyEvent.php',
        'pocketmine\\event\\player\\PlayerBucketEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBucketEvent.php',
        'pocketmine\\event\\player\\PlayerBucketFillEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerBucketFillEvent.php',
        'pocketmine\\event\\player\\PlayerChangeSkinEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerChangeSkinEvent.php',
        'pocketmine\\event\\player\\PlayerChatEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerChatEvent.php',
        'pocketmine\\event\\player\\PlayerCommandPreprocessEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php',
        'pocketmine\\event\\player\\PlayerCreationEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerCreationEvent.php',
        'pocketmine\\event\\player\\PlayerDataSaveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerDataSaveEvent.php',
        'pocketmine\\event\\player\\PlayerDeathEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerDeathEvent.php',
        'pocketmine\\event\\player\\PlayerDropItemEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerDropItemEvent.php',
        'pocketmine\\event\\player\\PlayerEditBookEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerEditBookEvent.php',
        'pocketmine\\event\\player\\PlayerEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerEvent.php',
        'pocketmine\\event\\player\\PlayerExhaustEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerExhaustEvent.php',
        'pocketmine\\event\\player\\PlayerExperienceChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerExperienceChangeEvent.php',
        'pocketmine\\event\\player\\PlayerGameModeChangeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerGameModeChangeEvent.php',
        'pocketmine\\event\\player\\PlayerInteractEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerInteractEvent.php',
        'pocketmine\\event\\player\\PlayerItemConsumeEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerItemConsumeEvent.php',
        'pocketmine\\event\\player\\PlayerItemHeldEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerItemHeldEvent.php',
        'pocketmine\\event\\player\\PlayerJoinEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerJoinEvent.php',
        'pocketmine\\event\\player\\PlayerJumpEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerJumpEvent.php',
        'pocketmine\\event\\player\\PlayerKickEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerKickEvent.php',
        'pocketmine\\event\\player\\PlayerLoginEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerLoginEvent.php',
        'pocketmine\\event\\player\\PlayerMoveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerMoveEvent.php',
        'pocketmine\\event\\player\\PlayerPreLoginEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerPreLoginEvent.php',
        'pocketmine\\event\\player\\PlayerQuitEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerQuitEvent.php',
        'pocketmine\\event\\player\\PlayerRespawnEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerRespawnEvent.php',
        'pocketmine\\event\\player\\PlayerToggleFlightEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerToggleFlightEvent.php',
        'pocketmine\\event\\player\\PlayerToggleSneakEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerToggleSneakEvent.php',
        'pocketmine\\event\\player\\PlayerToggleSprintEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerToggleSprintEvent.php',
        'pocketmine\\event\\player\\PlayerTransferEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/PlayerTransferEvent.php',
        'pocketmine\\event\\player\\cheat\\PlayerCheatEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/cheat/PlayerCheatEvent.php',
        'pocketmine\\event\\player\\cheat\\PlayerIllegalMoveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php',
        'pocketmine\\event\\plugin\\PluginDisableEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/plugin/PluginDisableEvent.php',
        'pocketmine\\event\\plugin\\PluginEnableEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/plugin/PluginEnableEvent.php',
        'pocketmine\\event\\plugin\\PluginEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/plugin/PluginEvent.php',
        'pocketmine\\event\\server\\CommandEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/CommandEvent.php',
        'pocketmine\\event\\server\\DataPacketReceiveEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/DataPacketReceiveEvent.php',
        'pocketmine\\event\\server\\DataPacketSendEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/DataPacketSendEvent.php',
        'pocketmine\\event\\server\\LowMemoryEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/LowMemoryEvent.php',
        'pocketmine\\event\\server\\NetworkInterfaceCrashEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php',
        'pocketmine\\event\\server\\NetworkInterfaceEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/NetworkInterfaceEvent.php',
        'pocketmine\\event\\server\\NetworkInterfaceRegisterEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php',
        'pocketmine\\event\\server\\NetworkInterfaceUnregisterEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/NetworkInterfaceUnregisterEvent.php',
        'pocketmine\\event\\server\\QueryRegenerateEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/QueryRegenerateEvent.php',
        'pocketmine\\event\\server\\RemoteServerCommandEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/RemoteServerCommandEvent.php',
        'pocketmine\\event\\server\\ServerCommandEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/ServerCommandEvent.php',
        'pocketmine\\event\\server\\ServerEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/ServerEvent.php',
        'pocketmine\\event\\server\\UpdateNotifyEvent' => __DIR__ . '/../..' . '/src/pocketmine/event/server/UpdateNotifyEvent.php',
        'pocketmine\\form\\Form' => __DIR__ . '/../..' . '/src/pocketmine/form/Form.php',
        'pocketmine\\form\\FormValidationException' => __DIR__ . '/../..' . '/src/pocketmine/form/FormValidationException.php',
        'pocketmine\\inventory\\AnvilInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/AnvilInventory.php',
        'pocketmine\\inventory\\ArmorInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ArmorInventory.php',
        'pocketmine\\inventory\\ArmorInventoryEventProcessor' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ArmorInventoryEventProcessor.php',
        'pocketmine\\inventory\\BaseInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/BaseInventory.php',
        'pocketmine\\inventory\\ChestInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ChestInventory.php',
        'pocketmine\\inventory\\ContainerInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ContainerInventory.php',
        'pocketmine\\inventory\\CraftingGrid' => __DIR__ . '/../..' . '/src/pocketmine/inventory/CraftingGrid.php',
        'pocketmine\\inventory\\CraftingManager' => __DIR__ . '/../..' . '/src/pocketmine/inventory/CraftingManager.php',
        'pocketmine\\inventory\\CraftingRecipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/CraftingRecipe.php',
        'pocketmine\\inventory\\CustomInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/CustomInventory.php',
        'pocketmine\\inventory\\DoubleChestInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/DoubleChestInventory.php',
        'pocketmine\\inventory\\EnchantInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/EnchantInventory.php',
        'pocketmine\\inventory\\EnderChestInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/EnderChestInventory.php',
        'pocketmine\\inventory\\EntityInventoryEventProcessor' => __DIR__ . '/../..' . '/src/pocketmine/inventory/EntityInventoryEventProcessor.php',
        'pocketmine\\inventory\\FurnaceInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/FurnaceInventory.php',
        'pocketmine\\inventory\\FurnaceRecipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/FurnaceRecipe.php',
        'pocketmine\\inventory\\Inventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/Inventory.php',
        'pocketmine\\inventory\\InventoryEventProcessor' => __DIR__ . '/../..' . '/src/pocketmine/inventory/InventoryEventProcessor.php',
        'pocketmine\\inventory\\InventoryHolder' => __DIR__ . '/../..' . '/src/pocketmine/inventory/InventoryHolder.php',
        'pocketmine\\inventory\\MultiRecipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/MultiRecipe.php',
        'pocketmine\\inventory\\PlayerCursorInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/PlayerCursorInventory.php',
        'pocketmine\\inventory\\PlayerInventory' => __DIR__ . '/../..' . '/src/pocketmine/inventory/PlayerInventory.php',
        'pocketmine\\inventory\\Recipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/Recipe.php',
        'pocketmine\\inventory\\ShapedRecipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ShapedRecipe.php',
        'pocketmine\\inventory\\ShapelessRecipe' => __DIR__ . '/../..' . '/src/pocketmine/inventory/ShapelessRecipe.php',
        'pocketmine\\inventory\\transaction\\CraftingTransaction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/CraftingTransaction.php',
        'pocketmine\\inventory\\transaction\\InventoryTransaction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/InventoryTransaction.php',
        'pocketmine\\inventory\\transaction\\TransactionValidationException' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/TransactionValidationException.php',
        'pocketmine\\inventory\\transaction\\action\\CreativeInventoryAction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php',
        'pocketmine\\inventory\\transaction\\action\\DropItemAction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/action/DropItemAction.php',
        'pocketmine\\inventory\\transaction\\action\\InventoryAction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/action/InventoryAction.php',
        'pocketmine\\inventory\\transaction\\action\\SlotChangeAction' => __DIR__ . '/../..' . '/src/pocketmine/inventory/transaction/action/SlotChangeAction.php',
        'pocketmine\\item\\Apple' => __DIR__ . '/../..' . '/src/pocketmine/item/Apple.php',
        'pocketmine\\item\\Armor' => __DIR__ . '/../..' . '/src/pocketmine/item/Armor.php',
        'pocketmine\\item\\Arrow' => __DIR__ . '/../..' . '/src/pocketmine/item/Arrow.php',
        'pocketmine\\item\\Axe' => __DIR__ . '/../..' . '/src/pocketmine/item/Axe.php',
        'pocketmine\\item\\BakedPotato' => __DIR__ . '/../..' . '/src/pocketmine/item/BakedPotato.php',
        'pocketmine\\item\\Banner' => __DIR__ . '/../..' . '/src/pocketmine/item/Banner.php',
        'pocketmine\\item\\Bed' => __DIR__ . '/../..' . '/src/pocketmine/item/Bed.php',
        'pocketmine\\item\\Beetroot' => __DIR__ . '/../..' . '/src/pocketmine/item/Beetroot.php',
        'pocketmine\\item\\BeetrootSeeds' => __DIR__ . '/../..' . '/src/pocketmine/item/BeetrootSeeds.php',
        'pocketmine\\item\\BeetrootSoup' => __DIR__ . '/../..' . '/src/pocketmine/item/BeetrootSoup.php',
        'pocketmine\\item\\BlazeRod' => __DIR__ . '/../..' . '/src/pocketmine/item/BlazeRod.php',
        'pocketmine\\item\\Boat' => __DIR__ . '/../..' . '/src/pocketmine/item/Boat.php',
        'pocketmine\\item\\Book' => __DIR__ . '/../..' . '/src/pocketmine/item/Book.php',
        'pocketmine\\item\\Bow' => __DIR__ . '/../..' . '/src/pocketmine/item/Bow.php',
        'pocketmine\\item\\Bowl' => __DIR__ . '/../..' . '/src/pocketmine/item/Bowl.php',
        'pocketmine\\item\\Bread' => __DIR__ . '/../..' . '/src/pocketmine/item/Bread.php',
        'pocketmine\\item\\Bucket' => __DIR__ . '/../..' . '/src/pocketmine/item/Bucket.php',
        'pocketmine\\item\\Carrot' => __DIR__ . '/../..' . '/src/pocketmine/item/Carrot.php',
        'pocketmine\\item\\ChainBoots' => __DIR__ . '/../..' . '/src/pocketmine/item/ChainBoots.php',
        'pocketmine\\item\\ChainChestplate' => __DIR__ . '/../..' . '/src/pocketmine/item/ChainChestplate.php',
        'pocketmine\\item\\ChainHelmet' => __DIR__ . '/../..' . '/src/pocketmine/item/ChainHelmet.php',
        'pocketmine\\item\\ChainLeggings' => __DIR__ . '/../..' . '/src/pocketmine/item/ChainLeggings.php',
        'pocketmine\\item\\ChorusFruit' => __DIR__ . '/../..' . '/src/pocketmine/item/ChorusFruit.php',
        'pocketmine\\item\\Clock' => __DIR__ . '/../..' . '/src/pocketmine/item/Clock.php',
        'pocketmine\\item\\Clownfish' => __DIR__ . '/../..' . '/src/pocketmine/item/Clownfish.php',
        'pocketmine\\item\\Coal' => __DIR__ . '/../..' . '/src/pocketmine/item/Coal.php',
        'pocketmine\\item\\Compass' => __DIR__ . '/../..' . '/src/pocketmine/item/Compass.php',
        'pocketmine\\item\\Consumable' => __DIR__ . '/../..' . '/src/pocketmine/item/Consumable.php',
        'pocketmine\\item\\CookedChicken' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedChicken.php',
        'pocketmine\\item\\CookedFish' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedFish.php',
        'pocketmine\\item\\CookedMutton' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedMutton.php',
        'pocketmine\\item\\CookedPorkchop' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedPorkchop.php',
        'pocketmine\\item\\CookedRabbit' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedRabbit.php',
        'pocketmine\\item\\CookedSalmon' => __DIR__ . '/../..' . '/src/pocketmine/item/CookedSalmon.php',
        'pocketmine\\item\\Cookie' => __DIR__ . '/../..' . '/src/pocketmine/item/Cookie.php',
        'pocketmine\\item\\DiamondBoots' => __DIR__ . '/../..' . '/src/pocketmine/item/DiamondBoots.php',
        'pocketmine\\item\\DiamondChestplate' => __DIR__ . '/../..' . '/src/pocketmine/item/DiamondChestplate.php',
        'pocketmine\\item\\DiamondHelmet' => __DIR__ . '/../..' . '/src/pocketmine/item/DiamondHelmet.php',
        'pocketmine\\item\\DiamondLeggings' => __DIR__ . '/../..' . '/src/pocketmine/item/DiamondLeggings.php',
        'pocketmine\\item\\DriedKelp' => __DIR__ . '/../..' . '/src/pocketmine/item/DriedKelp.php',
        'pocketmine\\item\\Durable' => __DIR__ . '/../..' . '/src/pocketmine/item/Durable.php',
        'pocketmine\\item\\Dye' => __DIR__ . '/../..' . '/src/pocketmine/item/Dye.php',
        'pocketmine\\item\\Egg' => __DIR__ . '/../..' . '/src/pocketmine/item/Egg.php',
        'pocketmine\\item\\EnderPearl' => __DIR__ . '/../..' . '/src/pocketmine/item/EnderPearl.php',
        'pocketmine\\item\\ExperienceBottle' => __DIR__ . '/../..' . '/src/pocketmine/item/ExperienceBottle.php',
        'pocketmine\\item\\FishingRod' => __DIR__ . '/../..' . '/src/pocketmine/item/FishingRod.php',
        'pocketmine\\item\\FlintSteel' => __DIR__ . '/../..' . '/src/pocketmine/item/FlintSteel.php',
        'pocketmine\\item\\Food' => __DIR__ . '/../..' . '/src/pocketmine/item/Food.php',
        'pocketmine\\item\\FoodSource' => __DIR__ . '/../..' . '/src/pocketmine/item/FoodSource.php',
        'pocketmine\\item\\GlassBottle' => __DIR__ . '/../..' . '/src/pocketmine/item/GlassBottle.php',
        'pocketmine\\item\\GoldBoots' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldBoots.php',
        'pocketmine\\item\\GoldChestplate' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldChestplate.php',
        'pocketmine\\item\\GoldHelmet' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldHelmet.php',
        'pocketmine\\item\\GoldLeggings' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldLeggings.php',
        'pocketmine\\item\\GoldenApple' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldenApple.php',
        'pocketmine\\item\\GoldenAppleEnchanted' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldenAppleEnchanted.php',
        'pocketmine\\item\\GoldenCarrot' => __DIR__ . '/../..' . '/src/pocketmine/item/GoldenCarrot.php',
        'pocketmine\\item\\Hoe' => __DIR__ . '/../..' . '/src/pocketmine/item/Hoe.php',
        'pocketmine\\item\\IronBoots' => __DIR__ . '/../..' . '/src/pocketmine/item/IronBoots.php',
        'pocketmine\\item\\IronChestplate' => __DIR__ . '/../..' . '/src/pocketmine/item/IronChestplate.php',
        'pocketmine\\item\\IronHelmet' => __DIR__ . '/../..' . '/src/pocketmine/item/IronHelmet.php',
        'pocketmine\\item\\IronLeggings' => __DIR__ . '/../..' . '/src/pocketmine/item/IronLeggings.php',
        'pocketmine\\item\\Item' => __DIR__ . '/../..' . '/src/pocketmine/item/Item.php',
        'pocketmine\\item\\ItemBlock' => __DIR__ . '/../..' . '/src/pocketmine/item/ItemBlock.php',
        'pocketmine\\item\\ItemFactory' => __DIR__ . '/../..' . '/src/pocketmine/item/ItemFactory.php',
        'pocketmine\\item\\ItemIds' => __DIR__ . '/../..' . '/src/pocketmine/item/ItemIds.php',
        'pocketmine\\item\\LeatherBoots' => __DIR__ . '/../..' . '/src/pocketmine/item/LeatherBoots.php',
        'pocketmine\\item\\LeatherCap' => __DIR__ . '/../..' . '/src/pocketmine/item/LeatherCap.php',
        'pocketmine\\item\\LeatherPants' => __DIR__ . '/../..' . '/src/pocketmine/item/LeatherPants.php',
        'pocketmine\\item\\LeatherTunic' => __DIR__ . '/../..' . '/src/pocketmine/item/LeatherTunic.php',
        'pocketmine\\item\\MaybeConsumable' => __DIR__ . '/../..' . '/src/pocketmine/item/MaybeConsumable.php',
        'pocketmine\\item\\Melon' => __DIR__ . '/../..' . '/src/pocketmine/item/Melon.php',
        'pocketmine\\item\\MelonSeeds' => __DIR__ . '/../..' . '/src/pocketmine/item/MelonSeeds.php',
        'pocketmine\\item\\Minecart' => __DIR__ . '/../..' . '/src/pocketmine/item/Minecart.php',
        'pocketmine\\item\\MushroomStew' => __DIR__ . '/../..' . '/src/pocketmine/item/MushroomStew.php',
        'pocketmine\\item\\PaintingItem' => __DIR__ . '/../..' . '/src/pocketmine/item/PaintingItem.php',
        'pocketmine\\item\\Pickaxe' => __DIR__ . '/../..' . '/src/pocketmine/item/Pickaxe.php',
        'pocketmine\\item\\PoisonousPotato' => __DIR__ . '/../..' . '/src/pocketmine/item/PoisonousPotato.php',
        'pocketmine\\item\\Potato' => __DIR__ . '/../..' . '/src/pocketmine/item/Potato.php',
        'pocketmine\\item\\Potion' => __DIR__ . '/../..' . '/src/pocketmine/item/Potion.php',
        'pocketmine\\item\\ProjectileItem' => __DIR__ . '/../..' . '/src/pocketmine/item/ProjectileItem.php',
        'pocketmine\\item\\Pufferfish' => __DIR__ . '/../..' . '/src/pocketmine/item/Pufferfish.php',
        'pocketmine\\item\\PumpkinPie' => __DIR__ . '/../..' . '/src/pocketmine/item/PumpkinPie.php',
        'pocketmine\\item\\PumpkinSeeds' => __DIR__ . '/../..' . '/src/pocketmine/item/PumpkinSeeds.php',
        'pocketmine\\item\\RabbitStew' => __DIR__ . '/../..' . '/src/pocketmine/item/RabbitStew.php',
        'pocketmine\\item\\RawBeef' => __DIR__ . '/../..' . '/src/pocketmine/item/RawBeef.php',
        'pocketmine\\item\\RawChicken' => __DIR__ . '/../..' . '/src/pocketmine/item/RawChicken.php',
        'pocketmine\\item\\RawFish' => __DIR__ . '/../..' . '/src/pocketmine/item/RawFish.php',
        'pocketmine\\item\\RawMutton' => __DIR__ . '/../..' . '/src/pocketmine/item/RawMutton.php',
        'pocketmine\\item\\RawPorkchop' => __DIR__ . '/../..' . '/src/pocketmine/item/RawPorkchop.php',
        'pocketmine\\item\\RawRabbit' => __DIR__ . '/../..' . '/src/pocketmine/item/RawRabbit.php',
        'pocketmine\\item\\RawSalmon' => __DIR__ . '/../..' . '/src/pocketmine/item/RawSalmon.php',
        'pocketmine\\item\\Redstone' => __DIR__ . '/../..' . '/src/pocketmine/item/Redstone.php',
        'pocketmine\\item\\RottenFlesh' => __DIR__ . '/../..' . '/src/pocketmine/item/RottenFlesh.php',
        'pocketmine\\item\\Shears' => __DIR__ . '/../..' . '/src/pocketmine/item/Shears.php',
        'pocketmine\\item\\Shovel' => __DIR__ . '/../..' . '/src/pocketmine/item/Shovel.php',
        'pocketmine\\item\\Sign' => __DIR__ . '/../..' . '/src/pocketmine/item/Sign.php',
        'pocketmine\\item\\Snowball' => __DIR__ . '/../..' . '/src/pocketmine/item/Snowball.php',
        'pocketmine\\item\\SpawnEgg' => __DIR__ . '/../..' . '/src/pocketmine/item/SpawnEgg.php',
        'pocketmine\\item\\SpiderEye' => __DIR__ . '/../..' . '/src/pocketmine/item/SpiderEye.php',
        'pocketmine\\item\\SplashPotion' => __DIR__ . '/../..' . '/src/pocketmine/item/SplashPotion.php',
        'pocketmine\\item\\Steak' => __DIR__ . '/../..' . '/src/pocketmine/item/Steak.php',
        'pocketmine\\item\\Stick' => __DIR__ . '/../..' . '/src/pocketmine/item/Stick.php',
        'pocketmine\\item\\StringItem' => __DIR__ . '/../..' . '/src/pocketmine/item/StringItem.php',
        'pocketmine\\item\\Sword' => __DIR__ . '/../..' . '/src/pocketmine/item/Sword.php',
        'pocketmine\\item\\TieredTool' => __DIR__ . '/../..' . '/src/pocketmine/item/TieredTool.php',
        'pocketmine\\item\\Tool' => __DIR__ . '/../..' . '/src/pocketmine/item/Tool.php',
        'pocketmine\\item\\Totem' => __DIR__ . '/../..' . '/src/pocketmine/item/Totem.php',
        'pocketmine\\item\\WheatSeeds' => __DIR__ . '/../..' . '/src/pocketmine/item/WheatSeeds.php',
        'pocketmine\\item\\WritableBook' => __DIR__ . '/../..' . '/src/pocketmine/item/WritableBook.php',
        'pocketmine\\item\\WrittenBook' => __DIR__ . '/../..' . '/src/pocketmine/item/WrittenBook.php',
        'pocketmine\\item\\enchantment\\Enchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/Enchantment.php',
        'pocketmine\\item\\enchantment\\EnchantmentEntry' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/EnchantmentEntry.php',
        'pocketmine\\item\\enchantment\\EnchantmentInstance' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/EnchantmentInstance.php',
        'pocketmine\\item\\enchantment\\EnchantmentList' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/EnchantmentList.php',
        'pocketmine\\item\\enchantment\\FireAspectEnchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/FireAspectEnchantment.php',
        'pocketmine\\item\\enchantment\\KnockbackEnchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/KnockbackEnchantment.php',
        'pocketmine\\item\\enchantment\\MeleeWeaponEnchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/MeleeWeaponEnchantment.php',
        'pocketmine\\item\\enchantment\\ProtectionEnchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/ProtectionEnchantment.php',
        'pocketmine\\item\\enchantment\\SharpnessEnchantment' => __DIR__ . '/../..' . '/src/pocketmine/item/enchantment/SharpnessEnchantment.php',
        'pocketmine\\lang\\BaseLang' => __DIR__ . '/../..' . '/src/pocketmine/lang/BaseLang.php',
        'pocketmine\\lang\\TextContainer' => __DIR__ . '/../..' . '/src/pocketmine/lang/TextContainer.php',
        'pocketmine\\lang\\TranslationContainer' => __DIR__ . '/../..' . '/src/pocketmine/lang/TranslationContainer.php',
        'pocketmine\\level\\ChunkLoader' => __DIR__ . '/../..' . '/src/pocketmine/level/ChunkLoader.php',
        'pocketmine\\level\\ChunkManager' => __DIR__ . '/../..' . '/src/pocketmine/level/ChunkManager.php',
        'pocketmine\\level\\Explosion' => __DIR__ . '/../..' . '/src/pocketmine/level/Explosion.php',
        'pocketmine\\level\\Level' => __DIR__ . '/../..' . '/src/pocketmine/level/Level.php',
        'pocketmine\\level\\LevelException' => __DIR__ . '/../..' . '/src/pocketmine/level/LevelException.php',
        'pocketmine\\level\\LevelTimings' => __DIR__ . '/../..' . '/src/pocketmine/level/LevelTimings.php',
        'pocketmine\\level\\Location' => __DIR__ . '/../..' . '/src/pocketmine/level/Location.php',
        'pocketmine\\level\\Position' => __DIR__ . '/../..' . '/src/pocketmine/level/Position.php',
        'pocketmine\\level\\SimpleChunkManager' => __DIR__ . '/../..' . '/src/pocketmine/level/SimpleChunkManager.php',
        'pocketmine\\level\\biome\\Biome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/Biome.php',
        'pocketmine\\level\\biome\\DesertBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/DesertBiome.php',
        'pocketmine\\level\\biome\\ForestBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/ForestBiome.php',
        'pocketmine\\level\\biome\\GrassyBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/GrassyBiome.php',
        'pocketmine\\level\\biome\\HellBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/HellBiome.php',
        'pocketmine\\level\\biome\\IcePlainsBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/IcePlainsBiome.php',
        'pocketmine\\level\\biome\\MountainsBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/MountainsBiome.php',
        'pocketmine\\level\\biome\\OceanBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/OceanBiome.php',
        'pocketmine\\level\\biome\\PlainBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/PlainBiome.php',
        'pocketmine\\level\\biome\\RiverBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/RiverBiome.php',
        'pocketmine\\level\\biome\\SandyBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/SandyBiome.php',
        'pocketmine\\level\\biome\\SmallMountainsBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/SmallMountainsBiome.php',
        'pocketmine\\level\\biome\\SnowyBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/SnowyBiome.php',
        'pocketmine\\level\\biome\\SwampBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/SwampBiome.php',
        'pocketmine\\level\\biome\\TaigaBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/TaigaBiome.php',
        'pocketmine\\level\\biome\\UnknownBiome' => __DIR__ . '/../..' . '/src/pocketmine/level/biome/UnknownBiome.php',
        'pocketmine\\level\\format\\Chunk' => __DIR__ . '/../..' . '/src/pocketmine/level/format/Chunk.php',
        'pocketmine\\level\\format\\ChunkException' => __DIR__ . '/../..' . '/src/pocketmine/level/format/ChunkException.php',
        'pocketmine\\level\\format\\EmptySubChunk' => __DIR__ . '/../..' . '/src/pocketmine/level/format/EmptySubChunk.php',
        'pocketmine\\level\\format\\SubChunk' => __DIR__ . '/../..' . '/src/pocketmine/level/format/SubChunk.php',
        'pocketmine\\level\\format\\SubChunkInterface' => __DIR__ . '/../..' . '/src/pocketmine/level/format/SubChunkInterface.php',
        'pocketmine\\level\\format\\io\\BaseLevelProvider' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/BaseLevelProvider.php',
        'pocketmine\\level\\format\\io\\ChunkRequestTask' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/ChunkRequestTask.php',
        'pocketmine\\level\\format\\io\\ChunkUtils' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/ChunkUtils.php',
        'pocketmine\\level\\format\\io\\LevelProvider' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/LevelProvider.php',
        'pocketmine\\level\\format\\io\\LevelProviderManager' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/LevelProviderManager.php',
        'pocketmine\\level\\format\\io\\exception\\CorruptedChunkException' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/exception/CorruptedChunkException.php',
        'pocketmine\\level\\format\\io\\exception\\UnsupportedChunkFormatException' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/exception/UnsupportedChunkFormatException.php',
        'pocketmine\\level\\format\\io\\leveldb\\LevelDB' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/leveldb/LevelDB.php',
        'pocketmine\\level\\format\\io\\region\\Anvil' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/Anvil.php',
        'pocketmine\\level\\format\\io\\region\\CorruptedRegionException' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/CorruptedRegionException.php',
        'pocketmine\\level\\format\\io\\region\\McRegion' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/McRegion.php',
        'pocketmine\\level\\format\\io\\region\\PMAnvil' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/PMAnvil.php',
        'pocketmine\\level\\format\\io\\region\\RegionException' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/RegionException.php',
        'pocketmine\\level\\format\\io\\region\\RegionLoader' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/RegionLoader.php',
        'pocketmine\\level\\format\\io\\region\\RegionLocationTableEntry' => __DIR__ . '/../..' . '/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php',
        'pocketmine\\level\\generator\\Flat' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/Flat.php',
        'pocketmine\\level\\generator\\Generator' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/Generator.php',
        'pocketmine\\level\\generator\\GeneratorManager' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/GeneratorManager.php',
        'pocketmine\\level\\generator\\GeneratorRegisterTask' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/GeneratorRegisterTask.php',
        'pocketmine\\level\\generator\\GeneratorUnregisterTask' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/GeneratorUnregisterTask.php',
        'pocketmine\\level\\generator\\InvalidGeneratorOptionsException' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php',
        'pocketmine\\level\\generator\\PopulationTask' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/PopulationTask.php',
        'pocketmine\\level\\generator\\biome\\BiomeSelector' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/biome/BiomeSelector.php',
        'pocketmine\\level\\generator\\hell\\Nether' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/hell/Nether.php',
        'pocketmine\\level\\generator\\noise\\Noise' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/noise/Noise.php',
        'pocketmine\\level\\generator\\noise\\Perlin' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/noise/Perlin.php',
        'pocketmine\\level\\generator\\noise\\Simplex' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/noise/Simplex.php',
        'pocketmine\\level\\generator\\normal\\Normal' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/normal/Normal.php',
        'pocketmine\\level\\generator\\object\\BigTree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/BigTree.php',
        'pocketmine\\level\\generator\\object\\BirchTree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/BirchTree.php',
        'pocketmine\\level\\generator\\object\\JungleTree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/JungleTree.php',
        'pocketmine\\level\\generator\\object\\OakTree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/OakTree.php',
        'pocketmine\\level\\generator\\object\\Ore' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/Ore.php',
        'pocketmine\\level\\generator\\object\\OreType' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/OreType.php',
        'pocketmine\\level\\generator\\object\\Pond' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/Pond.php',
        'pocketmine\\level\\generator\\object\\PopulatorObject' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/PopulatorObject.php',
        'pocketmine\\level\\generator\\object\\SpruceTree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/SpruceTree.php',
        'pocketmine\\level\\generator\\object\\TallGrass' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/TallGrass.php',
        'pocketmine\\level\\generator\\object\\Tree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/object/Tree.php',
        'pocketmine\\level\\generator\\populator\\GroundCover' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/GroundCover.php',
        'pocketmine\\level\\generator\\populator\\Ore' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/Ore.php',
        'pocketmine\\level\\generator\\populator\\Pond' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/Pond.php',
        'pocketmine\\level\\generator\\populator\\Populator' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/Populator.php',
        'pocketmine\\level\\generator\\populator\\TallGrass' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/TallGrass.php',
        'pocketmine\\level\\generator\\populator\\Tree' => __DIR__ . '/../..' . '/src/pocketmine/level/generator/populator/Tree.php',
        'pocketmine\\level\\light\\BlockLightUpdate' => __DIR__ . '/../..' . '/src/pocketmine/level/light/BlockLightUpdate.php',
        'pocketmine\\level\\light\\LightPopulationTask' => __DIR__ . '/../..' . '/src/pocketmine/level/light/LightPopulationTask.php',
        'pocketmine\\level\\light\\LightUpdate' => __DIR__ . '/../..' . '/src/pocketmine/level/light/LightUpdate.php',
        'pocketmine\\level\\light\\SkyLightUpdate' => __DIR__ . '/../..' . '/src/pocketmine/level/light/SkyLightUpdate.php',
        'pocketmine\\level\\particle\\AngryVillagerParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/AngryVillagerParticle.php',
        'pocketmine\\level\\particle\\BlockForceFieldParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/BlockForceFieldParticle.php',
        'pocketmine\\level\\particle\\BubbleParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/BubbleParticle.php',
        'pocketmine\\level\\particle\\CriticalParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/CriticalParticle.php',
        'pocketmine\\level\\particle\\DestroyBlockParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/DestroyBlockParticle.php',
        'pocketmine\\level\\particle\\DustParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/DustParticle.php',
        'pocketmine\\level\\particle\\EnchantParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/EnchantParticle.php',
        'pocketmine\\level\\particle\\EnchantmentTableParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/EnchantmentTableParticle.php',
        'pocketmine\\level\\particle\\EntityFlameParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/EntityFlameParticle.php',
        'pocketmine\\level\\particle\\ExplodeParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/ExplodeParticle.php',
        'pocketmine\\level\\particle\\FlameParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/FlameParticle.php',
        'pocketmine\\level\\particle\\FloatingTextParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/FloatingTextParticle.php',
        'pocketmine\\level\\particle\\GenericParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/GenericParticle.php',
        'pocketmine\\level\\particle\\HappyVillagerParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/HappyVillagerParticle.php',
        'pocketmine\\level\\particle\\HeartParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/HeartParticle.php',
        'pocketmine\\level\\particle\\HugeExplodeParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/HugeExplodeParticle.php',
        'pocketmine\\level\\particle\\HugeExplodeSeedParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/HugeExplodeSeedParticle.php',
        'pocketmine\\level\\particle\\InkParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/InkParticle.php',
        'pocketmine\\level\\particle\\InstantEnchantParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/InstantEnchantParticle.php',
        'pocketmine\\level\\particle\\ItemBreakParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/ItemBreakParticle.php',
        'pocketmine\\level\\particle\\LavaDripParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/LavaDripParticle.php',
        'pocketmine\\level\\particle\\LavaParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/LavaParticle.php',
        'pocketmine\\level\\particle\\MobSpawnParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/MobSpawnParticle.php',
        'pocketmine\\level\\particle\\Particle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/Particle.php',
        'pocketmine\\level\\particle\\PortalParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/PortalParticle.php',
        'pocketmine\\level\\particle\\RainSplashParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/RainSplashParticle.php',
        'pocketmine\\level\\particle\\RedstoneParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/RedstoneParticle.php',
        'pocketmine\\level\\particle\\SmokeParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/SmokeParticle.php',
        'pocketmine\\level\\particle\\SnowballPoofParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/SnowballPoofParticle.php',
        'pocketmine\\level\\particle\\SplashParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/SplashParticle.php',
        'pocketmine\\level\\particle\\SporeParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/SporeParticle.php',
        'pocketmine\\level\\particle\\TerrainParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/TerrainParticle.php',
        'pocketmine\\level\\particle\\WaterDripParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/WaterDripParticle.php',
        'pocketmine\\level\\particle\\WaterParticle' => __DIR__ . '/../..' . '/src/pocketmine/level/particle/WaterParticle.php',
        'pocketmine\\level\\sound\\AnvilBreakSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/AnvilBreakSound.php',
        'pocketmine\\level\\sound\\AnvilFallSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/AnvilFallSound.php',
        'pocketmine\\level\\sound\\AnvilUseSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/AnvilUseSound.php',
        'pocketmine\\level\\sound\\BlazeShootSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/BlazeShootSound.php',
        'pocketmine\\level\\sound\\ClickSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/ClickSound.php',
        'pocketmine\\level\\sound\\DoorBumpSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/DoorBumpSound.php',
        'pocketmine\\level\\sound\\DoorCrashSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/DoorCrashSound.php',
        'pocketmine\\level\\sound\\DoorSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/DoorSound.php',
        'pocketmine\\level\\sound\\EndermanTeleportSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/EndermanTeleportSound.php',
        'pocketmine\\level\\sound\\FizzSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/FizzSound.php',
        'pocketmine\\level\\sound\\GenericSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/GenericSound.php',
        'pocketmine\\level\\sound\\GhastShootSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/GhastShootSound.php',
        'pocketmine\\level\\sound\\GhastSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/GhastSound.php',
        'pocketmine\\level\\sound\\LaunchSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/LaunchSound.php',
        'pocketmine\\level\\sound\\PopSound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/PopSound.php',
        'pocketmine\\level\\sound\\Sound' => __DIR__ . '/../..' . '/src/pocketmine/level/sound/Sound.php',
        'pocketmine\\level\\utils\\SubChunkIteratorManager' => __DIR__ . '/../..' . '/src/pocketmine/level/utils/SubChunkIteratorManager.php',
        'pocketmine\\math\\AxisAlignedBB' => __DIR__ . '/..' . '/pocketmine/math/src/AxisAlignedBB.php',
        'pocketmine\\math\\Math' => __DIR__ . '/..' . '/pocketmine/math/src/Math.php',
        'pocketmine\\math\\Matrix' => __DIR__ . '/..' . '/pocketmine/math/src/Matrix.php',
        'pocketmine\\math\\RayTraceResult' => __DIR__ . '/..' . '/pocketmine/math/src/RayTraceResult.php',
        'pocketmine\\math\\Vector2' => __DIR__ . '/..' . '/pocketmine/math/src/Vector2.php',
        'pocketmine\\math\\Vector3' => __DIR__ . '/..' . '/pocketmine/math/src/Vector3.php',
        'pocketmine\\math\\VectorMath' => __DIR__ . '/..' . '/pocketmine/math/src/VectorMath.php',
        'pocketmine\\math\\VoxelRayTrace' => __DIR__ . '/..' . '/pocketmine/math/src/VoxelRayTrace.php',
        'pocketmine\\metadata\\BlockMetadataStore' => __DIR__ . '/../..' . '/src/pocketmine/metadata/BlockMetadataStore.php',
        'pocketmine\\metadata\\EntityMetadataStore' => __DIR__ . '/../..' . '/src/pocketmine/metadata/EntityMetadataStore.php',
        'pocketmine\\metadata\\LevelMetadataStore' => __DIR__ . '/../..' . '/src/pocketmine/metadata/LevelMetadataStore.php',
        'pocketmine\\metadata\\MetadataStore' => __DIR__ . '/../..' . '/src/pocketmine/metadata/MetadataStore.php',
        'pocketmine\\metadata\\MetadataValue' => __DIR__ . '/../..' . '/src/pocketmine/metadata/MetadataValue.php',
        'pocketmine\\metadata\\Metadatable' => __DIR__ . '/../..' . '/src/pocketmine/metadata/Metadatable.php',
        'pocketmine\\metadata\\PlayerMetadataStore' => __DIR__ . '/../..' . '/src/pocketmine/metadata/PlayerMetadataStore.php',
        'pocketmine\\nbt\\BigEndianNBTStream' => __DIR__ . '/..' . '/pocketmine/nbt/src/BigEndianNBTStream.php',
        'pocketmine\\nbt\\JsonNbtParser' => __DIR__ . '/..' . '/pocketmine/nbt/src/JsonNbtParser.php',
        'pocketmine\\nbt\\LittleEndianNBTStream' => __DIR__ . '/..' . '/pocketmine/nbt/src/LittleEndianNBTStream.php',
        'pocketmine\\nbt\\NBT' => __DIR__ . '/..' . '/pocketmine/nbt/src/NBT.php',
        'pocketmine\\nbt\\NBTStream' => __DIR__ . '/..' . '/pocketmine/nbt/src/NBTStream.php',
        'pocketmine\\nbt\\NetworkLittleEndianNBTStream' => __DIR__ . '/..' . '/pocketmine/nbt/src/NetworkLittleEndianNBTStream.php',
        'pocketmine\\nbt\\ReaderTracker' => __DIR__ . '/..' . '/pocketmine/nbt/src/ReaderTracker.php',
        'pocketmine\\nbt\\tag\\ByteArrayTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/ByteArrayTag.php',
        'pocketmine\\nbt\\tag\\ByteTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/ByteTag.php',
        'pocketmine\\nbt\\tag\\CompoundTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/CompoundTag.php',
        'pocketmine\\nbt\\tag\\DoubleTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/DoubleTag.php',
        'pocketmine\\nbt\\tag\\FloatTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/FloatTag.php',
        'pocketmine\\nbt\\tag\\IntArrayTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/IntArrayTag.php',
        'pocketmine\\nbt\\tag\\IntTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/IntTag.php',
        'pocketmine\\nbt\\tag\\ListTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/ListTag.php',
        'pocketmine\\nbt\\tag\\LongTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/LongTag.php',
        'pocketmine\\nbt\\tag\\NamedTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/NamedTag.php',
        'pocketmine\\nbt\\tag\\NoDynamicFieldsTrait' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/NoDynamicFieldsTrait.php',
        'pocketmine\\nbt\\tag\\ShortTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/ShortTag.php',
        'pocketmine\\nbt\\tag\\StringTag' => __DIR__ . '/..' . '/pocketmine/nbt/src/tag/StringTag.php',
        'pocketmine\\network\\AdvancedSourceInterface' => __DIR__ . '/../..' . '/src/pocketmine/network/AdvancedSourceInterface.php',
        'pocketmine\\network\\CompressBatchedTask' => __DIR__ . '/../..' . '/src/pocketmine/network/CompressBatchedTask.php',
        'pocketmine\\network\\Network' => __DIR__ . '/../..' . '/src/pocketmine/network/Network.php',
        'pocketmine\\network\\SourceInterface' => __DIR__ . '/../..' . '/src/pocketmine/network/SourceInterface.php',
        'pocketmine\\network\\mcpe\\CachedEncapsulatedPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/CachedEncapsulatedPacket.php',
        'pocketmine\\network\\mcpe\\NetworkBinaryStream' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/NetworkBinaryStream.php',
        'pocketmine\\network\\mcpe\\NetworkSession' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/NetworkSession.php',
        'pocketmine\\network\\mcpe\\PlayerNetworkSessionAdapter' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php',
        'pocketmine\\network\\mcpe\\RakLibInterface' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/RakLibInterface.php',
        'pocketmine\\network\\mcpe\\VerifyLoginException' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/VerifyLoginException.php',
        'pocketmine\\network\\mcpe\\VerifyLoginTask' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/VerifyLoginTask.php',
        'pocketmine\\network\\mcpe\\protocol\\ActorEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ActorFallPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ActorFallPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ActorPickRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ActorPickRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddActorPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddActorPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddBehaviorTreePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddEntityPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddItemActorPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddPaintingPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AddPlayerPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AdventureSettingsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AnimatePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AnimatePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AnvilDamagePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AnvilDamagePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AutomationClientConnectPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AvailableActorIdentifiersPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\AvailableCommandsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BatchPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BatchPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BiomeDefinitionListPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BlockActorDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BlockActorDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BlockEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BlockPickRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BookEditPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BookEditPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\BossEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/BossEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CameraPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CameraPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ChangeDimensionPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ChunkRadiusUpdatedPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ClientCacheBlobStatusPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ClientCacheMissResponsePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ClientCacheStatusPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ClientCacheStatusPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ClientToServerHandshakePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ClientboundMapItemDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CommandBlockUpdatePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CommandOutputPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CommandRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CompletedUsingItemPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CompletedUsingItemPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ContainerClosePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ContainerOpenPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ContainerSetDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CraftingDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\CraftingEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\DataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/DataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\DisconnectPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\EducationSettingsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/EducationSettingsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\EmotePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/EmotePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\EventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/EventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\GameRulesChangedPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\GuiDataPickItemPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\HurtArmorPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\InteractPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/InteractPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\InventoryContentPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\InventorySlotPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\InventoryTransactionPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ItemFrameDropItemPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LabTablePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LabTablePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LecternUpdatePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelChunkPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelEventGenericPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelEventGenericPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelSoundEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelSoundEventPacketV1' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php',
        'pocketmine\\network\\mcpe\\protocol\\LevelSoundEventPacketV2' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php',
        'pocketmine\\network\\mcpe\\protocol\\LoginPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/LoginPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MapCreateLockedCopyPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MapInfoRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MobArmorEquipmentPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MobEffectPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MobEquipmentPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ModalFormRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ModalFormResponsePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MoveActorAbsolutePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MoveActorAbsolutePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MoveActorDeltaPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MovePlayerPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\MultiplayerSettingsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/MultiplayerSettingsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\NetworkChunkPublisherUpdatePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\NetworkSettingsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/NetworkSettingsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\NetworkStackLatencyPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\NpcRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\OnScreenTextureAnimationPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PacketPool' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PacketPool.php',
        'pocketmine\\network\\mcpe\\protocol\\PhotoTransferPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlaySoundPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayStatusPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerActionPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerAuthInputPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerAuthInputPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerHotbarPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerInputPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerListPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\PlayerSkinPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ProtocolInfo' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php',
        'pocketmine\\network\\mcpe\\protocol\\PurchaseReceiptPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RemoveActorPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RemoveActorPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RemoveEntityPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RemoveObjectivePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RequestChunkRadiusPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePackChunkDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePackChunkRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePackClientResponsePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePackDataInfoPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePackStackPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ResourcePacksInfoPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RespawnPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RespawnPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\RiderJumpPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ScriptCustomEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ServerSettingsRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ServerSettingsResponsePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ServerToClientHandshakePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetActorDataPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetActorLinkPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetActorMotionPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetActorMotionPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetCommandsEnabledPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetDefaultGameTypePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetDifficultyPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetDisplayObjectivePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetHealthPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetLastHurtByPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetLocalPlayerAsInitializedPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetPlayerGameTypePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetScorePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetScorePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetScoreboardIdentityPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetSpawnPositionPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetTimePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetTimePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SetTitlePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SettingsCommandPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SettingsCommandPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ShowCreditsPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ShowProfilePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\ShowStoreOfferPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SimpleEventPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SpawnExperienceOrbPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SpawnParticleEffectPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\StartGamePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/StartGamePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\StopSoundPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\StructureBlockUpdatePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\StructureTemplateDataRequestPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/StructureTemplateDataRequestPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\StructureTemplateDataResponsePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/StructureTemplateDataResponsePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\SubClientLoginPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\TakeItemActorPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/TakeItemActorPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\TextPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/TextPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\TickSyncPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/TickSyncPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\TransferPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/TransferPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UnknownPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UnknownPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateAttributesPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateBlockPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateBlockPropertiesPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateBlockPropertiesPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateBlockSyncedPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateEquipPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateSoftEnumPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\UpdateTradePacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php',
        'pocketmine\\network\\mcpe\\protocol\\VideoStreamConnectPacket' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\ChunkCacheBlob' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/ChunkCacheBlob.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandData' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandData.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandEnum' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandEnumConstraint' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandEnumConstraint.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandOriginData' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandOriginData.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandOutputMessage' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandOutputMessage.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\CommandParameter' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\ContainerIds' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\DimensionIds' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/DimensionIds.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\EntityLink' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/EntityLink.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\InputMode' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/InputMode.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\LegacySkinAdapter' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/LegacySkinAdapter.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\MapDecoration' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/MapDecoration.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\MapTrackedObject' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/MapTrackedObject.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\NetworkInventoryAction' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\PlayMode' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/PlayMode.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\PlayerListEntry' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\PlayerPermissions' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/PlayerPermissions.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\PotionContainerChangeRecipe' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/PotionContainerChangeRecipe.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\PotionTypeRecipe' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/PotionTypeRecipe.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\ResourcePackType' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\RuntimeBlockMapping' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\ScorePacketEntry' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/ScorePacketEntry.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\ScoreboardIdentityPacketEntry' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\SkinAdapter' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/SkinAdapter.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\SkinAdapterSingleton' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/SkinAdapterSingleton.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\SkinAnimation' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/SkinAnimation.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\SkinData' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/SkinData.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\SkinImage' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/SkinImage.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\StructureSettings' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/StructureSettings.php',
        'pocketmine\\network\\mcpe\\protocol\\types\\WindowTypes' => __DIR__ . '/../..' . '/src/pocketmine/network/mcpe/protocol/types/WindowTypes.php',
        'pocketmine\\network\\query\\QueryHandler' => __DIR__ . '/../..' . '/src/pocketmine/network/query/QueryHandler.php',
        'pocketmine\\network\\rcon\\RCON' => __DIR__ . '/../..' . '/src/pocketmine/network/rcon/RCON.php',
        'pocketmine\\network\\rcon\\RCONInstance' => __DIR__ . '/../..' . '/src/pocketmine/network/rcon/RCONInstance.php',
        'pocketmine\\network\\upnp\\UPnP' => __DIR__ . '/../..' . '/src/pocketmine/network/upnp/UPnP.php',
        'pocketmine\\permission\\BanEntry' => __DIR__ . '/../..' . '/src/pocketmine/permission/BanEntry.php',
        'pocketmine\\permission\\BanList' => __DIR__ . '/../..' . '/src/pocketmine/permission/BanList.php',
        'pocketmine\\permission\\DefaultPermissions' => __DIR__ . '/../..' . '/src/pocketmine/permission/DefaultPermissions.php',
        'pocketmine\\permission\\Permissible' => __DIR__ . '/../..' . '/src/pocketmine/permission/Permissible.php',
        'pocketmine\\permission\\PermissibleBase' => __DIR__ . '/../..' . '/src/pocketmine/permission/PermissibleBase.php',
        'pocketmine\\permission\\Permission' => __DIR__ . '/../..' . '/src/pocketmine/permission/Permission.php',
        'pocketmine\\permission\\PermissionAttachment' => __DIR__ . '/../..' . '/src/pocketmine/permission/PermissionAttachment.php',
        'pocketmine\\permission\\PermissionAttachmentInfo' => __DIR__ . '/../..' . '/src/pocketmine/permission/PermissionAttachmentInfo.php',
        'pocketmine\\permission\\PermissionManager' => __DIR__ . '/../..' . '/src/pocketmine/permission/PermissionManager.php',
        'pocketmine\\permission\\PermissionRemovedExecutor' => __DIR__ . '/../..' . '/src/pocketmine/permission/PermissionRemovedExecutor.php',
        'pocketmine\\permission\\ServerOperator' => __DIR__ . '/../..' . '/src/pocketmine/permission/ServerOperator.php',
        'pocketmine\\plugin\\EventExecutor' => __DIR__ . '/../..' . '/src/pocketmine/plugin/EventExecutor.php',
        'pocketmine\\plugin\\MethodEventExecutor' => __DIR__ . '/../..' . '/src/pocketmine/plugin/MethodEventExecutor.php',
        'pocketmine\\plugin\\PharPluginLoader' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PharPluginLoader.php',
        'pocketmine\\plugin\\Plugin' => __DIR__ . '/../..' . '/src/pocketmine/plugin/Plugin.php',
        'pocketmine\\plugin\\PluginBase' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginBase.php',
        'pocketmine\\plugin\\PluginDescription' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginDescription.php',
        'pocketmine\\plugin\\PluginException' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginException.php',
        'pocketmine\\plugin\\PluginLoadOrder' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginLoadOrder.php',
        'pocketmine\\plugin\\PluginLoader' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginLoader.php',
        'pocketmine\\plugin\\PluginLogger' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginLogger.php',
        'pocketmine\\plugin\\PluginManager' => __DIR__ . '/../..' . '/src/pocketmine/plugin/PluginManager.php',
        'pocketmine\\plugin\\RegisteredListener' => __DIR__ . '/../..' . '/src/pocketmine/plugin/RegisteredListener.php',
        'pocketmine\\plugin\\ScriptPluginLoader' => __DIR__ . '/../..' . '/src/pocketmine/plugin/ScriptPluginLoader.php',
        'pocketmine\\resourcepacks\\ResourcePack' => __DIR__ . '/../..' . '/src/pocketmine/resourcepacks/ResourcePack.php',
        'pocketmine\\resourcepacks\\ResourcePackException' => __DIR__ . '/../..' . '/src/pocketmine/resourcepacks/ResourcePackException.php',
        'pocketmine\\resourcepacks\\ResourcePackInfoEntry' => __DIR__ . '/../..' . '/src/pocketmine/resourcepacks/ResourcePackInfoEntry.php',
        'pocketmine\\resourcepacks\\ResourcePackManager' => __DIR__ . '/../..' . '/src/pocketmine/resourcepacks/ResourcePackManager.php',
        'pocketmine\\resourcepacks\\ZippedResourcePack' => __DIR__ . '/../..' . '/src/pocketmine/resourcepacks/ZippedResourcePack.php',
        'pocketmine\\scheduler\\AsyncPool' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/AsyncPool.php',
        'pocketmine\\scheduler\\AsyncTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/AsyncTask.php',
        'pocketmine\\scheduler\\AsyncWorker' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/AsyncWorker.php',
        'pocketmine\\scheduler\\BulkCurlTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/BulkCurlTask.php',
        'pocketmine\\scheduler\\ClosureTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/ClosureTask.php',
        'pocketmine\\scheduler\\DumpWorkerMemoryTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/DumpWorkerMemoryTask.php',
        'pocketmine\\scheduler\\FileWriteTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/FileWriteTask.php',
        'pocketmine\\scheduler\\GarbageCollectionTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/GarbageCollectionTask.php',
        'pocketmine\\scheduler\\SendUsageTask' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/SendUsageTask.php',
        'pocketmine\\scheduler\\Task' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/Task.php',
        'pocketmine\\scheduler\\TaskHandler' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/TaskHandler.php',
        'pocketmine\\scheduler\\TaskScheduler' => __DIR__ . '/../..' . '/src/pocketmine/scheduler/TaskScheduler.php',
        'pocketmine\\snooze\\SleeperHandler' => __DIR__ . '/..' . '/pocketmine/snooze/src/SleeperHandler.php',
        'pocketmine\\snooze\\SleeperNotifier' => __DIR__ . '/..' . '/pocketmine/snooze/src/SleeperNotifier.php',
        'pocketmine\\snooze\\ThreadedSleeper' => __DIR__ . '/..' . '/pocketmine/snooze/src/ThreadedSleeper.php',
        'pocketmine\\tile\\Banner' => __DIR__ . '/../..' . '/src/pocketmine/tile/Banner.php',
        'pocketmine\\tile\\Bed' => __DIR__ . '/../..' . '/src/pocketmine/tile/Bed.php',
        'pocketmine\\tile\\Chest' => __DIR__ . '/../..' . '/src/pocketmine/tile/Chest.php',
        'pocketmine\\tile\\Container' => __DIR__ . '/../..' . '/src/pocketmine/tile/Container.php',
        'pocketmine\\tile\\ContainerTrait' => __DIR__ . '/../..' . '/src/pocketmine/tile/ContainerTrait.php',
        'pocketmine\\tile\\EnchantTable' => __DIR__ . '/../..' . '/src/pocketmine/tile/EnchantTable.php',
        'pocketmine\\tile\\EnderChest' => __DIR__ . '/../..' . '/src/pocketmine/tile/EnderChest.php',
        'pocketmine\\tile\\FlowerPot' => __DIR__ . '/../..' . '/src/pocketmine/tile/FlowerPot.php',
        'pocketmine\\tile\\Furnace' => __DIR__ . '/../..' . '/src/pocketmine/tile/Furnace.php',
        'pocketmine\\tile\\ItemFrame' => __DIR__ . '/../..' . '/src/pocketmine/tile/ItemFrame.php',
        'pocketmine\\tile\\Nameable' => __DIR__ . '/../..' . '/src/pocketmine/tile/Nameable.php',
        'pocketmine\\tile\\NameableTrait' => __DIR__ . '/../..' . '/src/pocketmine/tile/NameableTrait.php',
        'pocketmine\\tile\\Sign' => __DIR__ . '/../..' . '/src/pocketmine/tile/Sign.php',
        'pocketmine\\tile\\Skull' => __DIR__ . '/../..' . '/src/pocketmine/tile/Skull.php',
        'pocketmine\\tile\\Spawnable' => __DIR__ . '/../..' . '/src/pocketmine/tile/Spawnable.php',
        'pocketmine\\tile\\Tile' => __DIR__ . '/../..' . '/src/pocketmine/tile/Tile.php',
        'pocketmine\\timings\\Timings' => __DIR__ . '/../..' . '/src/pocketmine/timings/Timings.php',
        'pocketmine\\timings\\TimingsHandler' => __DIR__ . '/../..' . '/src/pocketmine/timings/TimingsHandler.php',
        'pocketmine\\updater\\AutoUpdater' => __DIR__ . '/../..' . '/src/pocketmine/updater/AutoUpdater.php',
        'pocketmine\\updater\\UpdateCheckTask' => __DIR__ . '/../..' . '/src/pocketmine/updater/UpdateCheckTask.php',
        'pocketmine\\utils\\Binary' => __DIR__ . '/..' . '/pocketmine/binaryutils/src/Binary.php',
        'pocketmine\\utils\\BinaryDataException' => __DIR__ . '/..' . '/pocketmine/binaryutils/src/BinaryDataException.php',
        'pocketmine\\utils\\BinaryStream' => __DIR__ . '/..' . '/pocketmine/binaryutils/src/BinaryStream.php',
        'pocketmine\\utils\\Color' => __DIR__ . '/../..' . '/src/pocketmine/utils/Color.php',
        'pocketmine\\utils\\Config' => __DIR__ . '/../..' . '/src/pocketmine/utils/Config.php',
        'pocketmine\\utils\\Git' => __DIR__ . '/../..' . '/src/pocketmine/utils/Git.php',
        'pocketmine\\utils\\Internet' => __DIR__ . '/../..' . '/src/pocketmine/utils/Internet.php',
        'pocketmine\\utils\\InternetException' => __DIR__ . '/../..' . '/src/pocketmine/utils/InternetException.php',
        'pocketmine\\utils\\MainLogger' => __DIR__ . '/../..' . '/src/pocketmine/utils/MainLogger.php',
        'pocketmine\\utils\\Random' => __DIR__ . '/../..' . '/src/pocketmine/utils/Random.php',
        'pocketmine\\utils\\ReversePriorityQueue' => __DIR__ . '/../..' . '/src/pocketmine/utils/ReversePriorityQueue.php',
        'pocketmine\\utils\\ServerException' => __DIR__ . '/../..' . '/src/pocketmine/utils/ServerException.php',
        'pocketmine\\utils\\ServerKiller' => __DIR__ . '/../..' . '/src/pocketmine/utils/ServerKiller.php',
        'pocketmine\\utils\\Terminal' => __DIR__ . '/../..' . '/src/pocketmine/utils/Terminal.php',
        'pocketmine\\utils\\TextFormat' => __DIR__ . '/../..' . '/src/pocketmine/utils/TextFormat.php',
        'pocketmine\\utils\\Timezone' => __DIR__ . '/../..' . '/src/pocketmine/utils/Timezone.php',
        'pocketmine\\utils\\UUID' => __DIR__ . '/../..' . '/src/pocketmine/utils/UUID.php',
        'pocketmine\\utils\\Utils' => __DIR__ . '/../..' . '/src/pocketmine/utils/Utils.php',
        'pocketmine\\utils\\VersionString' => __DIR__ . '/../..' . '/src/pocketmine/utils/VersionString.php',
        'pocketmine\\wizard\\SetupWizard' => __DIR__ . '/../..' . '/src/pocketmine/wizard/SetupWizard.php',
        'raklib\\RakLib' => __DIR__ . '/..' . '/pocketmine/raklib/src/RakLib.php',
        'raklib\\protocol\\ACK' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/ACK.php',
        'raklib\\protocol\\AcknowledgePacket' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/AcknowledgePacket.php',
        'raklib\\protocol\\AdvertiseSystem' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/AdvertiseSystem.php',
        'raklib\\protocol\\ConnectedPing' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/ConnectedPing.php',
        'raklib\\protocol\\ConnectedPong' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/ConnectedPong.php',
        'raklib\\protocol\\ConnectionRequest' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/ConnectionRequest.php',
        'raklib\\protocol\\ConnectionRequestAccepted' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/ConnectionRequestAccepted.php',
        'raklib\\protocol\\Datagram' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/Datagram.php',
        'raklib\\protocol\\DisconnectionNotification' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/DisconnectionNotification.php',
        'raklib\\protocol\\EncapsulatedPacket' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/EncapsulatedPacket.php',
        'raklib\\protocol\\IncompatibleProtocolVersion' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/IncompatibleProtocolVersion.php',
        'raklib\\protocol\\MessageIdentifiers' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/MessageIdentifiers.php',
        'raklib\\protocol\\NACK' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/NACK.php',
        'raklib\\protocol\\NewIncomingConnection' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/NewIncomingConnection.php',
        'raklib\\protocol\\OfflineMessage' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/OfflineMessage.php',
        'raklib\\protocol\\OpenConnectionReply1' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/OpenConnectionReply1.php',
        'raklib\\protocol\\OpenConnectionReply2' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/OpenConnectionReply2.php',
        'raklib\\protocol\\OpenConnectionRequest1' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/OpenConnectionRequest1.php',
        'raklib\\protocol\\OpenConnectionRequest2' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/OpenConnectionRequest2.php',
        'raklib\\protocol\\Packet' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/Packet.php',
        'raklib\\protocol\\PacketReliability' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/PacketReliability.php',
        'raklib\\protocol\\UnconnectedPing' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/UnconnectedPing.php',
        'raklib\\protocol\\UnconnectedPingOpenConnections' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/UnconnectedPingOpenConnections.php',
        'raklib\\protocol\\UnconnectedPong' => __DIR__ . '/..' . '/pocketmine/raklib/src/protocol/UnconnectedPong.php',
        'raklib\\server\\OfflineMessageHandler' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/OfflineMessageHandler.php',
        'raklib\\server\\RakLibServer' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/RakLibServer.php',
        'raklib\\server\\ServerHandler' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/ServerHandler.php',
        'raklib\\server\\ServerInstance' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/ServerInstance.php',
        'raklib\\server\\Session' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/Session.php',
        'raklib\\server\\SessionManager' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/SessionManager.php',
        'raklib\\server\\UDPServerSocket' => __DIR__ . '/..' . '/pocketmine/raklib/src/server/UDPServerSocket.php',
        'raklib\\utils\\InternetAddress' => __DIR__ . '/..' . '/pocketmine/raklib/src/utils/InternetAddress.php',
    );

    public static function getInitializer(ClassLoader $loader)
    {
        return \Closure::bind(function () use ($loader) {
            $loader->prefixLengthsPsr4 = ComposerStaticInit2465bc1320a965a378e5f39bc0181113::$prefixLengthsPsr4;
            $loader->prefixDirsPsr4 = ComposerStaticInit2465bc1320a965a378e5f39bc0181113::$prefixDirsPsr4;
            $loader->fallbackDirsPsr4 = ComposerStaticInit2465bc1320a965a378e5f39bc0181113::$fallbackDirsPsr4;
            $loader->classMap = ComposerStaticInit2465bc1320a965a378e5f39bc0181113::$classMap;

        }, null, ClassLoader::class);
    }
}
<?php

/*
 *
 *  ____            _        _   __  __ _                  __  __ ____
 * |  _ \ ___   ___| | _____| |_|  \/  (_)_ __   ___      |  \/  |  _ \
 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
 * |  __/ (_) | (__|   <  __/ |_| |  | | | | | |  __/_____| |  | |  __/
 * |_|   \___/ \___|_|\_\___|\__|_|  |_|_|_| |_|\___|     |_|  |_|_|
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @author PocketMine Team
 * @link http://www.pocketmine.net/
 *
 *
*/

declare(strict_types=1);

namespace pocketmine;

// composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_CORE_CONSTANTS_INCLUDED')){
	return;
}
define('pocketmine\_CORE_CONSTANTS_INCLUDED', true);

define('pocketmine\PATH', dirname(__DIR__, 2) . '/');
define('pocketmine\RESOURCE_PATH', __DIR__ . '/resources/');
<?php

/*
 *
 *  ____            _        _   __  __ _                  __  __ ____
 * |  _ \ ___   ___| | _____| |_|  \/  (_)_ __   ___      |  \/  |  _ \
 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
 * |  __/ (_) | (__|   <  __/ |_| |  | | | | | |  __/_____| |  | |  __/
 * |_|   \___/ \___|_|\_\___|\__|_|  |_|_|_| |_|\___|     |_|  |_|_|
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @author PocketMine Team
 * @link http://www.pocketmine.net/
 *
 *
*/

// composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_GLOBAL_CONSTANTS_INCLUDED')){
	return;
}
define('pocketmine\_GLOBAL_CONSTANTS_INCLUDED', true);

const INT32_MIN = -0x80000000;
const INT32_MAX = 0x7fffffff;
const INT32_MASK = 0xffffffff;
<?php

/*
 *
 *  ____            _        _   __  __ _                  __  __ ____
 * |  _ \ ___   ___| | _____| |_|  \/  (_)_ __   ___      |  \/  |  _ \
 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
 * |  __/ (_) | (__|   <  __/ |_| |  | | | | | |  __/_____| |  | |  __/
 * |_|   \___/ \___|_|\_\___|\__|_|  |_|_|_| |_|\___|     |_|  |_|_|
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @author PocketMine Team
 * @link http://www.pocketmine.net/
 *
 *
*/

declare(strict_types=1);

namespace pocketmine;

// composer autoload doesn't use require_once and also pthreads can inherit things
// TODO: drop this file and use a final class with constants
if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
	return;
}
const _VERSION_INFO_INCLUDED = true;

const NAME = "PocketMine-MP";
const BASE_VERSION = "3.11.6";
const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 1791;
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\server;

use raklib\utils\InternetAddress;
use function socket_bind;
use function socket_close;
use function socket_create;
use function socket_last_error;
use function socket_recvfrom;
use function socket_sendto;
use function socket_set_nonblock;
use function socket_set_option;
use function socket_strerror;
use function strlen;
use function trim;
use const AF_INET;
use const AF_INET6;
use const IPV6_V6ONLY;
use const SO_RCVBUF;
use const SO_REUSEADDR;
use const SO_SNDBUF;
use const SOCK_DGRAM;
use const SOCKET_EADDRINUSE;
use const SOL_SOCKET;
use const SOL_UDP;

class UDPServerSocket{
	/** @var resource */
	protected $socket;
	/**
	 * @var InternetAddress
	 */
	private $bindAddress;

	public function __construct(InternetAddress $bindAddress){
		$this->bindAddress = $bindAddress;
		$this->socket = socket_create($bindAddress->version === 4 ? AF_INET : AF_INET6, SOCK_DGRAM, SOL_UDP);

		if($bindAddress->version === 6){
			socket_set_option($this->socket, IPPROTO_IPV6, IPV6_V6ONLY, 1); //Don't map IPv4 to IPv6, the implementation can create another RakLib instance to handle IPv4
		}

		if(@socket_bind($this->socket, $bindAddress->ip, $bindAddress->port) === true){
			$this->setSendBuffer(1024 * 1024 * 8)->setRecvBuffer(1024 * 1024 * 8);
		}else{
			$error = socket_last_error($this->socket);
			if($error === SOCKET_EADDRINUSE){ //platform error messages aren't consistent
				throw new \RuntimeException("Failed to bind socket: Something else is already running on $bindAddress");
			}
			throw new \RuntimeException("Failed to bind to " . $bindAddress . ": " . trim(socket_strerror(socket_last_error($this->socket))));
		}
		socket_set_nonblock($this->socket);
	}

	/**
	 * @return InternetAddress
	 */
	public function getBindAddress() : InternetAddress{
		return $this->bindAddress;
	}

	/**
	 * @return resource
	 */
	public function getSocket(){
		return $this->socket;
	}

	public function close() : void{
		socket_close($this->socket);
	}

	public function getLastError() : int{
		return socket_last_error($this->socket);
	}

	/**
	 * @param string $buffer reference parameter
	 * @param string $source reference parameter
	 * @param int    $port reference parameter
	 *
	 * @return int|bool
	 */
	public function readPacket(?string &$buffer, ?string &$source, ?int &$port){
		return @socket_recvfrom($this->socket, $buffer, 65535, 0, $source, $port);
	}

	/**
	 * @param string $buffer
	 * @param string $dest
	 * @param int    $port
	 *
	 * @return int|bool
	 */
	public function writePacket(string $buffer, string $dest, int $port){
		return socket_sendto($this->socket, $buffer, strlen($buffer), 0, $dest, $port);
	}

	/**
	 * @param int $size
	 *
	 * @return $this
	 */
	public function setSendBuffer(int $size){
		@socket_set_option($this->socket, SOL_SOCKET, SO_SNDBUF, $size);

		return $this;
	}

	/**
	 * @param int $size
	 *
	 * @return $this
	 */
	public function setRecvBuffer(int $size){
		@socket_set_option($this->socket, SOL_SOCKET, SO_RCVBUF, $size);

		return $this;
	}

}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\utils;

class InternetAddress{

	/**
	 * @var string
	 */
	public $ip;
	/**
	 * @var int
	 */
	public $port;
	/**
	 * @var int
	 */
	public $version;

	public function __construct(string $address, int $port, int $version){
		$this->ip = $address;
		if($port < 0 or $port > 65535){
			throw new \InvalidArgumentException("Invalid port range");
		}
		$this->port = $port;
		$this->version = $version;
	}

	/**
	 * @return string
	 */
	public function getIp() : string{
		return $this->ip;
	}

	/**
	 * @return int
	 */
	public function getPort() : int{
		return $this->port;
	}

	/**
	 * @return int
	 */
	public function getVersion() : int{
		return $this->version;
	}

	public function __toString(){
		return $this->ip . " " . $this->port;
	}

	public function toString() : string{
		return $this->__toString();
	}

	public function equals(InternetAddress $address) : bool{
		return $this->ip === $address->ip and $this->port === $address->port and $this->version === $address->version;
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\server;

use pocketmine\utils\Binary;
use raklib\protocol\ACK;
use raklib\protocol\AdvertiseSystem;
use raklib\protocol\Datagram;
use raklib\protocol\EncapsulatedPacket;
use raklib\protocol\NACK;
use raklib\protocol\OfflineMessage;
use raklib\protocol\OpenConnectionReply1;
use raklib\protocol\OpenConnectionReply2;
use raklib\protocol\OpenConnectionRequest1;
use raklib\protocol\OpenConnectionRequest2;
use raklib\protocol\Packet;
use raklib\protocol\UnconnectedPing;
use raklib\protocol\UnconnectedPingOpenConnections;
use raklib\protocol\UnconnectedPong;
use raklib\RakLib;
use raklib\utils\InternetAddress;
use function asort;
use function bin2hex;
use function chr;
use function count;
use function dechex;
use function get_class;
use function max;
use function microtime;
use function ord;
use function serialize;
use function socket_strerror;
use function strlen;
use function substr;
use function time;
use function time_sleep_until;
use function trim;
use const PHP_INT_MAX;
use const SOCKET_ECONNRESET;
use const SOCKET_EWOULDBLOCK;

class SessionManager{

	private const RAKLIB_TPS = 100;
	private const RAKLIB_TIME_PER_TICK = 1 / self::RAKLIB_TPS;

	/** @var \SplFixedArray<Packet|null> */
	protected $packetPool;

	/** @var RakLibServer */
	protected $server;
	/** @var UDPServerSocket */
	protected $socket;

	/** @var int */
	protected $receiveBytes = 0;
	/** @var int */
	protected $sendBytes = 0;

	/** @var Session[] */
	protected $sessions = [];

	/** @var OfflineMessageHandler */
	protected $offlineMessageHandler;
	/** @var string */
	protected $name = "";

	/** @var int */
	protected $packetLimit = 200;

	/** @var bool */
	protected $shutdown = false;

	/** @var int */
	protected $ticks = 0;
	/** @var float */
	protected $lastMeasure;

	/** @var int[] string (address) => int (unblock time) */
	protected $block = [];
	/** @var int[] string (address) => int (number of packets) */
	protected $ipSec = [];

	public $portChecking = false;

	/** @var int */
	protected $startTimeMS;

	/** @var int */
	protected $maxMtuSize;

	protected $reusableAddress;

	public function __construct(RakLibServer $server, UDPServerSocket $socket, int $maxMtuSize){
		$this->server = $server;
		$this->socket = $socket;

		$this->startTimeMS = (int) (microtime(true) * 1000);
		$this->maxMtuSize = $maxMtuSize;

		$this->offlineMessageHandler = new OfflineMessageHandler($this);

		$this->reusableAddress = clone $this->socket->getBindAddress();

		$this->registerPackets();

		$this->run();
	}

	/**
	 * Returns the time in milliseconds since server start.
	 * @return int
	 */
	public function getRakNetTimeMS() : int{
		return ((int) (microtime(true) * 1000)) - $this->startTimeMS;
	}

	public function getPort() : int{
		return $this->socket->getBindAddress()->port;
	}

	public function getMaxMtuSize() : int{
		return $this->maxMtuSize;
	}

	public function getProtocolVersion() : int{
		return $this->server->getProtocolVersion();
	}

	public function getLogger() : \ThreadedLogger{
		return $this->server->getLogger();
	}

	public function run() : void{
		$this->tickProcessor();
	}

	private function tickProcessor() : void{
		$this->lastMeasure = microtime(true);

		while(!$this->shutdown){
			$start = microtime(true);

			/*
			 * The below code is designed to allow co-op between sending and receiving to avoid slowing down either one
			 * when high traffic is coming either way. Yielding will occur after 100 messages.
			 */
			do{
				for($stream = true, $i = 0; $i < 100 && $stream && !$this->shutdown; ++$i){
					$stream = $this->receiveStream();
				}

				for($socket = true, $i = 0; $i < 100 && $socket && !$this->shutdown; ++$i){
					$socket = $this->receivePacket();
				}
			}while(!$this->shutdown && ($stream || $socket));

			$this->tick();

			$time = microtime(true) - $start;
			if($time < self::RAKLIB_TIME_PER_TICK){
				@time_sleep_until(microtime(true) + self::RAKLIB_TIME_PER_TICK - $time);
			}
		}
	}

	private function tick() : void{
		$time = microtime(true);
		foreach($this->sessions as $session){
			$session->update($time);
		}

		$this->ipSec = [];

		if(($this->ticks % self::RAKLIB_TPS) === 0){
			if($this->sendBytes > 0 or $this->receiveBytes > 0){
				$diff = max(0.005, $time - $this->lastMeasure);
				$this->streamOption("bandwidth", serialize([
					"up" => $this->sendBytes / $diff,
					"down" => $this->receiveBytes / $diff
				]));
				$this->sendBytes = 0;
				$this->receiveBytes = 0;
			}
			$this->lastMeasure = $time;

			if(count($this->block) > 0){
				asort($this->block);
				$now = time();
				foreach($this->block as $address => $timeout){
					if($timeout <= $now){
						unset($this->block[$address]);
					}else{
						break;
					}
				}
			}
		}

		++$this->ticks;
	}


	private function receivePacket() : bool{
		$address = $this->reusableAddress;

		$len = $this->socket->readPacket($buffer, $address->ip, $address->port);
		if($len === false){
			$error = $this->socket->getLastError();
			if($error === SOCKET_EWOULDBLOCK){ //no data
				return false;
			}elseif($error === SOCKET_ECONNRESET){ //client disconnected improperly, maybe crash or lost connection
				return true;
			}

			$this->getLogger()->debug("Socket error occurred while trying to recv ($error): " . trim(socket_strerror($error)));
			return false;
		}

		$this->receiveBytes += $len;
		if(isset($this->block[$address->ip])){
			return true;
		}

		if(isset($this->ipSec[$address->ip])){
			if(++$this->ipSec[$address->ip] >= $this->packetLimit){
				$this->blockAddress($address->ip);
				return true;
			}
		}else{
			$this->ipSec[$address->ip] = 1;
		}

		if($len < 1){
			return true;
		}

		try{
			$pid = ord($buffer[0]);

			$session = $this->getSession($address);
			if($session !== null){
				if(($pid & Datagram::BITFLAG_VALID) !== 0){
					if($pid & Datagram::BITFLAG_ACK){
						$session->handlePacket(new ACK($buffer));
					}elseif($pid & Datagram::BITFLAG_NAK){
						$session->handlePacket(new NACK($buffer));
					}else{
						$session->handlePacket(new Datagram($buffer));
					}
				}else{
					$this->server->getLogger()->debug("Ignored unconnected packet from $address due to session already opened (0x" . dechex($pid) . ")");
				}
			}elseif(($pk = $this->getPacketFromPool($pid, $buffer)) instanceof OfflineMessage){
				/** @var OfflineMessage $pk */

				do{
					try{
						$pk->decode();
						if(!$pk->isValid()){
							throw new \InvalidArgumentException("Packet magic is invalid");
						}
					}catch(\Throwable $e){
						$logger = $this->server->getLogger();
						$logger->debug("Received garbage message from $address (" . $e->getMessage() . "): " . bin2hex($pk->getBuffer()));
						foreach($this->server->getTrace(0, $e->getTrace()) as $line){
							$logger->debug($line);
						}
						$this->blockAddress($address->ip, 5);
						break;
					}

					if(!$this->offlineMessageHandler->handle($pk, $address)){
						$this->server->getLogger()->debug("Unhandled unconnected packet " . get_class($pk) . " received from $address");
					}
				}while(false);
			}elseif(($pid & Datagram::BITFLAG_VALID) !== 0 and ($pid & 0x03) === 0){
				// Loose datagram, don't relay it as a raw packet
				// RakNet does not currently use the 0x02 or 0x01 bitflags on any datagram header, so we can use
				// this to identify the difference between loose datagrams and packets like Query.
				$this->server->getLogger()->debug("Ignored connected packet from $address due to no session opened (0x" . dechex($pid) . ")");
			}else{
				$this->streamRaw($address, $buffer);
			}
		}catch(\Throwable $e){
			$logger = $this->getLogger();
			$logger->debug("Packet from $address (" . strlen($buffer) . " bytes): 0x" . bin2hex($buffer));
			$logger->logException($e);
			$this->blockAddress($address->ip, 5);
		}

		return true;
	}

	public function sendPacket(Packet $packet, InternetAddress $address) : void{
		$packet->encode();
		$this->sendBytes += $this->socket->writePacket($packet->getBuffer(), $address->ip, $address->port);
	}

	public function streamEncapsulated(Session $session, EncapsulatedPacket $packet, int $flags = RakLib::PRIORITY_NORMAL) : void{
		$id = $session->getAddress()->toString();
		$buffer = chr(RakLib::PACKET_ENCAPSULATED) . chr(strlen($id)) . $id . chr($flags) . $packet->toInternalBinary();
		$this->server->pushThreadToMainPacket($buffer);
	}

	public function streamRaw(InternetAddress $source, string $payload) : void{
		$buffer = chr(RakLib::PACKET_RAW) . chr(strlen($source->ip)) . $source->ip . (\pack("n", $source->port)) . $payload;
		$this->server->pushThreadToMainPacket($buffer);
	}

	protected function streamClose(string $identifier, string $reason) : void{
		$buffer = chr(RakLib::PACKET_CLOSE_SESSION) . chr(strlen($identifier)) . $identifier . chr(strlen($reason)) . $reason;
		$this->server->pushThreadToMainPacket($buffer);
	}

	protected function streamInvalid(string $identifier) : void{
		$buffer = chr(RakLib::PACKET_INVALID_SESSION) . chr(strlen($identifier)) . $identifier;
		$this->server->pushThreadToMainPacket($buffer);
	}

	protected function streamOpen(Session $session) : void{
		$address = $session->getAddress();
		$identifier = $address->toString();
		$buffer = chr(RakLib::PACKET_OPEN_SESSION) . chr(strlen($identifier)) . $identifier . chr(strlen($address->ip)) . $address->ip . (\pack("n", $address->port)) . (\pack("NN", $session->getID() >> 32, $session->getID() & 0xFFFFFFFF));
		$this->server->pushThreadToMainPacket($buffer);
	}

	protected function streamACK(string $identifier, int $identifierACK) : void{
		$buffer = chr(RakLib::PACKET_ACK_NOTIFICATION) . chr(strlen($identifier)) . $identifier . (\pack("N", $identifierACK));
		$this->server->pushThreadToMainPacket($buffer);
	}

	/**
	 * @param string $name
	 * @param mixed  $value
	 */
	protected function streamOption(string $name, $value) : void{
		$buffer = chr(RakLib::PACKET_SET_OPTION) . chr(strlen($name)) . $name . $value;
		$this->server->pushThreadToMainPacket($buffer);
	}

	public function streamPingMeasure(Session $session, int $pingMS) : void{
		$identifier = $session->getAddress()->toString();
		$buffer = chr(RakLib::PACKET_REPORT_PING) . chr(strlen($identifier)) . $identifier . (\pack("N", $pingMS));
		$this->server->pushThreadToMainPacket($buffer);
	}

	public function receiveStream() : bool{
		if(($packet = $this->server->readMainToThreadPacket()) !== null){
			$id = ord($packet[0]);
			$offset = 1;
			if($id === RakLib::PACKET_ENCAPSULATED){
				$len = ord($packet[$offset++]);
				$identifier = substr($packet, $offset, $len);
				$offset += $len;
				$session = $this->sessions[$identifier] ?? null;
				if($session !== null and $session->isConnected()){
					$flags = ord($packet[$offset++]);
					$buffer = substr($packet, $offset);
					$session->addEncapsulatedToQueue(EncapsulatedPacket::fromInternalBinary($buffer), $flags);
				}else{
					$this->streamInvalid($identifier);
				}
			}elseif($id === RakLib::PACKET_RAW){
				$len = ord($packet[$offset++]);
				$address = substr($packet, $offset, $len);
				$offset += $len;
				$port = (\unpack("n", substr($packet, $offset, 2))[1]);
				$offset += 2;
				$payload = substr($packet, $offset);
				$this->socket->writePacket($payload, $address, $port);
			}elseif($id === RakLib::PACKET_CLOSE_SESSION){
				$len = ord($packet[$offset++]);
				$identifier = substr($packet, $offset, $len);
				if(isset($this->sessions[$identifier])){
					$this->sessions[$identifier]->flagForDisconnection();
				}else{
					$this->streamInvalid($identifier);
				}
			}elseif($id === RakLib::PACKET_INVALID_SESSION){
				$len = ord($packet[$offset++]);
				$identifier = substr($packet, $offset, $len);
				if(isset($this->sessions[$identifier])){
					$this->removeSession($this->sessions[$identifier]);
				}
			}elseif($id === RakLib::PACKET_SET_OPTION){
				$len = ord($packet[$offset++]);
				$name = substr($packet, $offset, $len);
				$offset += $len;
				$value = substr($packet, $offset);
				switch($name){
					case "name":
						$this->name = $value;
						break;
					case "portChecking":
						$this->portChecking = (bool) $value;
						break;
					case "packetLimit":
						$this->packetLimit = (int) $value;
						break;
				}
			}elseif($id === RakLib::PACKET_BLOCK_ADDRESS){
				$len = ord($packet[$offset++]);
				$address = substr($packet, $offset, $len);
				$offset += $len;
				$timeout = (\unpack("N", substr($packet, $offset, 4))[1] << 32 >> 32);
				$this->blockAddress($address, $timeout);
			}elseif($id === RakLib::PACKET_UNBLOCK_ADDRESS){
				$len = ord($packet[$offset++]);
				$address = substr($packet, $offset, $len);
				$this->unblockAddress($address);
			}elseif($id === RakLib::PACKET_SHUTDOWN){
				foreach($this->sessions as $session){
					$this->removeSession($session);
				}

				$this->socket->close();
				$this->shutdown = true;
			}elseif($id === RakLib::PACKET_EMERGENCY_SHUTDOWN){
				$this->shutdown = true;
			}else{
				$this->getLogger()->debug("Unknown RakLib internal packet (ID 0x" . dechex($id) . ") received from main thread");
			}

			return true;
		}

		return false;
	}

	public function blockAddress(string $address, int $timeout = 300) : void{
		$final = time() + $timeout;
		if(!isset($this->block[$address]) or $timeout === -1){
			if($timeout === -1){
				$final = PHP_INT_MAX;
			}else{
				$this->getLogger()->notice("Blocked $address for $timeout seconds");
			}
			$this->block[$address] = $final;
		}elseif($this->block[$address] < $final){
			$this->block[$address] = $final;
		}
	}

	public function unblockAddress(string $address) : void{
		unset($this->block[$address]);
		$this->getLogger()->debug("Unblocked $address");
	}

	/**
	 * @param InternetAddress $address
	 *
	 * @return Session|null
	 */
	public function getSession(InternetAddress $address) : ?Session{
		return $this->sessions[$address->toString()] ?? null;
	}

	public function sessionExists(InternetAddress $address) : bool{
		return isset($this->sessions[$address->toString()]);
	}

	public function createSession(InternetAddress $address, int $clientId, int $mtuSize) : Session{
		$this->checkSessions();

		$this->sessions[$address->toString()] = $session = new Session($this, clone $address, $clientId, $mtuSize);
		$this->getLogger()->debug("Created session for $address with MTU size $mtuSize");

		return $session;
	}

	public function removeSession(Session $session, string $reason = "unknown") : void{
		$id = $session->getAddress()->toString();
		if(isset($this->sessions[$id])){
			$this->sessions[$id]->close();
			$this->removeSessionInternal($session);
			$this->streamClose($id, $reason);
		}
	}

	public function removeSessionInternal(Session $session) : void{
		unset($this->sessions[$session->getAddress()->toString()]);
	}

	public function openSession(Session $session) : void{
		$this->streamOpen($session);
	}

	private function checkSessions() : void{
		if(count($this->sessions) > 4096){
			foreach($this->sessions as $i => $s){
				if($s->isTemporal()){
					unset($this->sessions[$i]);
					if(count($this->sessions) <= 4096){
						break;
					}
				}
			}
		}
	}

	public function notifyACK(Session $session, int $identifierACK) : void{
		$this->streamACK($session->getAddress()->toString(), $identifierACK);
	}

	public function getName() : string{
		return $this->name;
	}

	public function getID() : int{
		return $this->server->getServerId();
	}

	/**
	 * @param int    $id
	 * @param string $class
	 */
	private function registerPacket(int $id, string $class) : void{
		$this->packetPool[$id] = new $class;
	}

	/**
	 * @param int    $id
	 * @param string $buffer
	 *
	 * @return Packet|null
	 */
	public function getPacketFromPool(int $id, string $buffer = "") : ?Packet{
		$pk = $this->packetPool[$id];
		if($pk !== null){
			$pk = clone $pk;
			$pk->buffer = $buffer;
			return $pk;
		}

		return null;
	}

	private function registerPackets() : void{
		$this->packetPool = new \SplFixedArray(256);

		$this->registerPacket(UnconnectedPing::$ID, UnconnectedPing::class);
		$this->registerPacket(UnconnectedPingOpenConnections::$ID, UnconnectedPingOpenConnections::class);
		$this->registerPacket(OpenConnectionRequest1::$ID, OpenConnectionRequest1::class);
		$this->registerPacket(OpenConnectionReply1::$ID, OpenConnectionReply1::class);
		$this->registerPacket(OpenConnectionRequest2::$ID, OpenConnectionRequest2::class);
		$this->registerPacket(OpenConnectionReply2::$ID, OpenConnectionReply2::class);
		$this->registerPacket(UnconnectedPong::$ID, UnconnectedPong::class);
		$this->registerPacket(AdvertiseSystem::$ID, AdvertiseSystem::class);
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\server;

use raklib\protocol\IncompatibleProtocolVersion;
use raklib\protocol\OfflineMessage;
use raklib\protocol\OpenConnectionReply1;
use raklib\protocol\OpenConnectionReply2;
use raklib\protocol\OpenConnectionRequest1;
use raklib\protocol\OpenConnectionRequest2;
use raklib\protocol\UnconnectedPing;
use raklib\protocol\UnconnectedPong;
use raklib\utils\InternetAddress;
use function min;

class OfflineMessageHandler{
	/** @var SessionManager */
	private $sessionManager;

	public function __construct(SessionManager $manager){
		$this->sessionManager = $manager;
	}

	public function handle(OfflineMessage $packet, InternetAddress $address) : bool{
		switch($packet::$ID){
			case UnconnectedPing::$ID:
				/** @var UnconnectedPing $packet */
				$pk = new UnconnectedPong();
				$pk->serverID = $this->sessionManager->getID();
				$pk->pingID = $packet->pingID;
				$pk->serverName = $this->sessionManager->getName();
				$this->sessionManager->sendPacket($pk, $address);
				return true;
			case OpenConnectionRequest1::$ID:
				/** @var OpenConnectionRequest1 $packet */
				$serverProtocol = $this->sessionManager->getProtocolVersion();
				if($packet->protocol !== $serverProtocol){
					$pk = new IncompatibleProtocolVersion();
					$pk->protocolVersion = $serverProtocol;
					$pk->serverId = $this->sessionManager->getID();
					$this->sessionManager->sendPacket($pk, $address);
					$this->sessionManager->getLogger()->notice("Refused connection from $address due to incompatible RakNet protocol version (expected $serverProtocol, got $packet->protocol)");
				}else{
					$pk = new OpenConnectionReply1();
					$pk->mtuSize = $packet->mtuSize + 28; //IP header size (20 bytes) + UDP header size (8 bytes)
					$pk->serverID = $this->sessionManager->getID();
					$this->sessionManager->sendPacket($pk, $address);
				}
				return true;
			case OpenConnectionRequest2::$ID:
				/** @var OpenConnectionRequest2 $packet */

				if($packet->serverAddress->port === $this->sessionManager->getPort() or !$this->sessionManager->portChecking){
					if($packet->mtuSize < Session::MIN_MTU_SIZE){
						$this->sessionManager->getLogger()->debug("Not creating session for $address due to bad MTU size $packet->mtuSize");
						return true;
					}
					$mtuSize = min($packet->mtuSize, $this->sessionManager->getMaxMtuSize()); //Max size, do not allow creating large buffers to fill server memory
					$pk = new OpenConnectionReply2();
					$pk->mtuSize = $mtuSize;
					$pk->serverID = $this->sessionManager->getID();
					$pk->clientAddress = $address;
					$this->sessionManager->sendPacket($pk, $address);
					$this->sessionManager->createSession($address, $packet->clientID, $mtuSize);
				}else{
					$this->sessionManager->getLogger()->debug("Not creating session for $address due to mismatched port, expected " . $this->sessionManager->getPort() . ", got " . $packet->serverAddress->port);
				}

				return true;
		}

		return false;
	}

}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class UnconnectedPing extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_UNCONNECTED_PING;

	/** @var int */
	public $pingID;

	protected function encodePayload() : void{
		($this->buffer .= (\pack("NN", $this->pingID >> 32, $this->pingID & 0xFFFFFFFF)));
		$this->writeMagic();
	}

	protected function decodePayload() : void{
		$this->pingID = (Binary::readLong($this->get(8)));
		$this->readMagic();
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use raklib\RakLib;

abstract class OfflineMessage extends Packet{
	/** @var string */
	protected $magic;

	protected function readMagic(){
		$this->magic = $this->get(16);
	}

	protected function writeMagic(){
		$this->put(RakLib::MAGIC);
	}

	public function isValid() : bool{
		return $this->magic === RakLib::MAGIC;
	}

}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\BinaryStream;
use raklib\utils\InternetAddress;
use function assert;
use function count;
use function explode;
use function inet_ntop;
use function inet_pton;
use function strlen;
use const AF_INET6;

use pocketmine\utils\Binary;

abstract class Packet extends BinaryStream{
	public static $ID = -1;

	/** @var float|null */
	public $sendTime;

	protected function getString() : string{
		return $this->get(((\unpack("n", $this->get(2))[1])));
	}

	protected function getAddress() : InternetAddress{
		$version = (\ord($this->get(1)));
		if($version === 4){
			$addr = ((~(\ord($this->get(1)))) & 0xff) . "." . ((~(\ord($this->get(1)))) & 0xff) . "." . ((~(\ord($this->get(1)))) & 0xff) . "." . ((~(\ord($this->get(1)))) & 0xff);
			$port = ((\unpack("n", $this->get(2))[1]));
			return new InternetAddress($addr, $port, $version);
		}elseif($version === 6){
			//http://man7.org/1/man-pages/man7/ipv6.7.html
			(\unpack("v", $this->get(2))[1]); //Family, AF_INET6
			$port = ((\unpack("n", $this->get(2))[1]));
			((\unpack("N", $this->get(4))[1] << 32 >> 32)); //flow info
			$addr = inet_ntop($this->get(16));
			((\unpack("N", $this->get(4))[1] << 32 >> 32)); //scope ID
			return new InternetAddress($addr, $port, $version);
		}else{
			throw new \UnexpectedValueException("Unknown IP address version $version");
		}
	}

	protected function putString(string $v) : void{
		($this->buffer .= (\pack("n", strlen($v))));
		($this->buffer .= $v);
	}

	protected function putAddress(InternetAddress $address) : void{
		($this->buffer .= \chr($address->version));
		if($address->version === 4){
			$parts = explode(".", $address->ip);
			assert(count($parts) === 4, "Wrong number of parts in IPv4 IP, expected 4, got " . count($parts));
			foreach($parts as $b){
				($this->buffer .= \chr((~((int) $b)) & 0xff));
			}
			($this->buffer .= (\pack("n", $address->port)));
		}elseif($address->version === 6){
			($this->buffer .= (\pack("v", AF_INET6)));
			($this->buffer .= (\pack("n", $address->port)));
			($this->buffer .= (\pack("N", 0)));
			($this->buffer .= inet_pton($address->ip));
			($this->buffer .= (\pack("N", 0)));
		}else{
			throw new \InvalidArgumentException("IP version $address->version is not supported");
		}
	}

	public function encode() : void{
		$this->reset();
		$this->encodeHeader();
		$this->encodePayload();
	}

	protected function encodeHeader() : void{
		($this->buffer .= \chr(static::$ID));
	}

	abstract protected function encodePayload() : void;

	public function decode() : void{
		$this->offset = 0;
		$this->decodeHeader();
		$this->decodePayload();
	}

	protected function decodeHeader() : void{
		(\ord($this->get(1))); //PID
	}

	abstract protected function decodePayload() : void;

	public function clean(){
		$this->buffer = "";
		$this->offset = 0;
		$this->sendTime = null;

		return $this;
	}
}
<?php

/*
 *
 *  ____            _        _   __  __ _                  __  __ ____
 * |  _ \ ___   ___| | _____| |_|  \/  (_)_ __   ___      |  \/  |  _ \
 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
 * |  __/ (_) | (__|   <  __/ |_| |  | | | | | |  __/_____| |  | |  __/
 * |_|   \___/ \___|_|\_\___|\__|_|  |_|_|_| |_|\___|     |_|  |_|_|
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @author PocketMine Team
 * @link http://www.pocketmine.net/
 *
 *
*/

declare(strict_types=1);

namespace pocketmine\utils;


use function chr;
use function ord;
use function strlen;
use function substr;

class BinaryStream{

	/** @var int */
	public $offset;
	/** @var string */
	public $buffer;

	public function __construct(string $buffer = "", int $offset = 0){
		$this->buffer = $buffer;
		$this->offset = $offset;
	}

	/**
	 * @return void
	 */
	public function reset(){
		$this->buffer = "";
		$this->offset = 0;
	}

	/**
	 * Rewinds the stream pointer to the start.
	 */
	public function rewind() : void{
		$this->offset = 0;
	}

	public function setOffset(int $offset) : void{
		$this->offset = $offset;
	}

	/**
	 * @return void
	 */
	public function setBuffer(string $buffer = "", int $offset = 0){
		$this->buffer = $buffer;
		$this->offset = $offset;
	}

	public function getOffset() : int{
		return $this->offset;
	}

	public function getBuffer() : string{
		return $this->buffer;
	}

	/**
	 * @param int|true $len
	 *
	 * @return string
	 *
	 * @throws BinaryDataException if there are not enough bytes left in the buffer
	 */
	public function get($len) : string{
		if($len === 0){
			return "";
		}

		$buflen = strlen($this->buffer);
		if($len === true){
			$str = substr($this->buffer, $this->offset);
			$this->offset = $buflen;
			return $str;
		}
		if($len < 0){
			$this->offset = $buflen - 1;
			return "";
		}
		$remaining = $buflen - $this->offset;
		if($remaining < $len){
			throw new BinaryDataException("Not enough bytes left in buffer: need $len, have $remaining");
		}

		return $len === 1 ? $this->buffer[$this->offset++] : substr($this->buffer, ($this->offset += $len) - $len, $len);
	}

	/**
	 * @return string
	 * @throws BinaryDataException
	 */
	public function getRemaining() : string{
		$buflen = strlen($this->buffer);
		if($this->offset >= $buflen){
			throw new BinaryDataException("No bytes left to read");
		}
		$str = substr($this->buffer, $this->offset);
		$this->offset = $buflen;
		return $str;
	}

	/**
	 * @return void
	 */
	public function put(string $str){
		$this->buffer .= $str;
	}


	public function getBool() : bool{
		return $this->get(1) !== "\x00";
	}

	/**
	 * @return void
	 */
	public function putBool(bool $v){
		$this->buffer .= ($v ? "\x01" : "\x00");
	}


	public function getByte() : int{
		return ord($this->get(1));
	}

	/**
	 * @return void
	 */
	public function putByte(int $v){
		$this->buffer .= chr($v);
	}


	public function getShort() : int{
		return (\unpack("n", $this->get(2))[1]);
	}

	public function getSignedShort() : int{
		return (\unpack("n", $this->get(2))[1] << 48 >> 48);
	}

	/**
	 * @return void
	 */
	public function putShort(int $v){
		$this->buffer .= (\pack("n", $v));
	}

	public function getLShort() : int{
		return (\unpack("v", $this->get(2))[1]);
	}

	public function getSignedLShort() : int{
		return (\unpack("v", $this->get(2))[1] << 48 >> 48);
	}

	/**
	 * @return void
	 */
	public function putLShort(int $v){
		$this->buffer .= (\pack("v", $v));
	}


	public function getTriad() : int{
		return (\unpack("N", "\x00" . $this->get(3))[1]);
	}

	/**
	 * @return void
	 */
	public function putTriad(int $v){
		$this->buffer .= (\substr(\pack("N", $v), 1));
	}

	public function getLTriad() : int{
		return (\unpack("V", $this->get(3) . "\x00")[1]);
	}

	/**
	 * @return void
	 */
	public function putLTriad(int $v){
		$this->buffer .= (\substr(\pack("V", $v), 0, -1));
	}


	public function getInt() : int{
		return (\unpack("N", $this->get(4))[1] << 32 >> 32);
	}

	/**
	 * @return void
	 */
	public function putInt(int $v){
		$this->buffer .= (\pack("N", $v));
	}

	public function getLInt() : int{
		return (\unpack("V", $this->get(4))[1] << 32 >> 32);
	}

	/**
	 * @return void
	 */
	public function putLInt(int $v){
		$this->buffer .= (\pack("V", $v));
	}


	public function getFloat() : float{
		return (\unpack("G", $this->get(4))[1]);
	}

	public function getRoundedFloat(int $accuracy) : float{
		return (\round((\unpack("G", $this->get(4))[1]),  $accuracy));
	}

	/**
	 * @return void
	 */
	public function putFloat(float $v){
		$this->buffer .= (\pack("G", $v));
	}

	public function getLFloat() : float{
		return (\unpack("g", $this->get(4))[1]);
	}

	public function getRoundedLFloat(int $accuracy) : float{
		return (\round((\unpack("g", $this->get(4))[1]),  $accuracy));
	}

	/**
	 * @return void
	 */
	public function putLFloat(float $v){
		$this->buffer .= (\pack("g", $v));
	}

	public function getDouble() : float{
		return (\unpack("E", $this->get(8))[1]);
	}

	public function putDouble(float $v) : void{
		$this->buffer .= (\pack("E", $v));
	}

	public function getLDouble() : float{
		return (\unpack("e", $this->get(8))[1]);
	}

	public function putLDouble(float $v) : void{
		$this->buffer .= (\pack("e", $v));
	}

	/**
	 * @return int
	 */
	public function getLong() : int{
		return Binary::readLong($this->get(8));
	}

	/**
	 * @param int $v
	 *
	 * @return void
	 */
	public function putLong(int $v){
		$this->buffer .= (\pack("NN", $v >> 32, $v & 0xFFFFFFFF));
	}

	/**
	 * @return int
	 */
	public function getLLong() : int{
		return Binary::readLLong($this->get(8));
	}

	/**
	 * @param int $v
	 *
	 * @return void
	 */
	public function putLLong(int $v){
		$this->buffer .= (\pack("VV", $v & 0xFFFFFFFF, $v >> 32));
	}

	/**
	 * Reads a 32-bit variable-length unsigned integer from the buffer and returns it.
	 * @return int
	 */
	public function getUnsignedVarInt() : int{
		return Binary::readUnsignedVarInt($this->buffer, $this->offset);
	}

	/**
	 * Writes a 32-bit variable-length unsigned integer to the end of the buffer.
	 * @param int $v
	 *
	 * @return void
	 */
	public function putUnsignedVarInt(int $v){
		($this->buffer .= Binary::writeUnsignedVarInt($v));
	}

	/**
	 * Reads a 32-bit zigzag-encoded variable-length integer from the buffer and returns it.
	 * @return int
	 */
	public function getVarInt() : int{
		return Binary::readVarInt($this->buffer, $this->offset);
	}

	/**
	 * Writes a 32-bit zigzag-encoded variable-length integer to the end of the buffer.
	 * @param int $v
	 *
	 * @return void
	 */
	public function putVarInt(int $v){
		($this->buffer .= Binary::writeVarInt($v));
	}

	/**
	 * Reads a 64-bit variable-length integer from the buffer and returns it.
	 * @return int
	 */
	public function getUnsignedVarLong() : int{
		return Binary::readUnsignedVarLong($this->buffer, $this->offset);
	}

	/**
	 * Writes a 64-bit variable-length integer to the end of the buffer.
	 * @param int $v
	 *
	 * @return void
	 */
	public function putUnsignedVarLong(int $v){
		$this->buffer .= Binary::writeUnsignedVarLong($v);
	}

	/**
	 * Reads a 64-bit zigzag-encoded variable-length integer from the buffer and returns it.
	 * @return int
	 */
	public function getVarLong() : int{
		return Binary::readVarLong($this->buffer, $this->offset);
	}

	/**
	 * Writes a 64-bit zigzag-encoded variable-length integer to the end of the buffer.
	 * @param int $v
	 *
	 * @return void
	 */
	public function putVarLong(int $v){
		$this->buffer .= Binary::writeVarLong($v);
	}

	/**
	 * Returns whether the offset has reached the end of the buffer.
	 * @return bool
	 */
	public function feof() : bool{
		return !isset($this->buffer[$this->offset]);
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;


interface MessageIdentifiers{
	//From https://github.com/OculusVR/RakNet/blob/master/Source/MessageIdentifiers.h

	//
	// RESERVED TYPES - DO NOT CHANGE THESE
	// All types from RakPeer
	//
	/// These types are never returned to the user.
	/// Ping from a connected system.  Update timestamps (internal use only)
	public const ID_CONNECTED_PING = 0x00;
	/// Ping from an unconnected system.  Reply but do not update timestamps. (internal use only)
	public const ID_UNCONNECTED_PING = 0x01;
	/// Ping from an unconnected system.  Only reply if we have open connections. Do not update timestamps. (internal use only)
	public const ID_UNCONNECTED_PING_OPEN_CONNECTIONS = 0x02;
	/// Pong from a connected system.  Update timestamps (internal use only)
	public const ID_CONNECTED_PONG = 0x03;
	/// A reliable packet to detect lost connections (internal use only)
	public const ID_DETECT_LOST_CONNECTIONS = 0x04;
	/// C2S: Initial query: Header(1), OfflineMesageID(16), Protocol number(1), Pad(toMTU), sent with no fragment set.
	/// If protocol fails on server, returns ID_INCOMPATIBLE_PROTOCOL_VERSION to client
	public const ID_OPEN_CONNECTION_REQUEST_1 = 0x05;
	/// S2C: Header(1), OfflineMesageID(16), server GUID(8), HasSecurity(1), Cookie(4, if HasSecurity)
	/// , public key (if do security is true), MTU(2). If public key fails on client, returns ID_PUBLIC_KEY_MISMATCH
	public const ID_OPEN_CONNECTION_REPLY_1 = 0x06;
	/// C2S: Header(1), OfflineMesageID(16), Cookie(4, if HasSecurity is true on the server), clientSupportsSecurity(1 bit),
	/// handshakeChallenge (if has security on both server and client), remoteBindingAddress(6), MTU(2), client GUID(8)
	/// Connection slot allocated if cookie is valid, server is not full, GUID and IP not already in use.
	public const ID_OPEN_CONNECTION_REQUEST_2 = 0x07;
	/// S2C: Header(1), OfflineMesageID(16), server GUID(8), mtu(2), doSecurity(1 bit), handshakeAnswer (if do security is true)
	public const ID_OPEN_CONNECTION_REPLY_2 = 0x08;
	/// C2S: Header(1), GUID(8), Timestamp, HasSecurity(1), Proof(32)
	public const ID_CONNECTION_REQUEST = 0x09;
	/// RakPeer - Remote system requires secure connections, pass a public key to RakPeerInterface::Connect()
	public const ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY = 0x0a;
	/// RakPeer - We passed a public key to RakPeerInterface::Connect(), but the other system did not have security turned on
	public const ID_OUR_SYSTEM_REQUIRES_SECURITY = 0x0b;
	/// RakPeer - Wrong public key passed to RakPeerInterface::Connect()
	public const ID_PUBLIC_KEY_MISMATCH = 0x0c;
	/// RakPeer - Same as ID_ADVERTISE_SYSTEM, but intended for internal use rather than being passed to the user.
	/// Second byte indicates type. Used currently for NAT punchthrough for receiver port advertisement. See ID_NAT_ADVERTISE_RECIPIENT_PORT
	public const ID_OUT_OF_BAND_INTERNAL = 0x0d;
	/// If RakPeerInterface::Send() is called where PacketReliability contains _WITH_ACK_RECEIPT, then on a later call to
	/// RakPeerInterface::Receive() you will get ID_SND_RECEIPT_ACKED or ID_SND_RECEIPT_LOSS. The message will be 5 bytes long,
	/// and bytes 1-4 inclusive will contain a number in native order containing a number that identifies this message.
	/// This number will be returned by RakPeerInterface::Send() or RakPeerInterface::SendList(). ID_SND_RECEIPT_ACKED means that
	/// the message arrived
	public const ID_SND_RECEIPT_ACKED = 0x0e;
	/// If RakPeerInterface::Send() is called where PacketReliability contains UNRELIABLE_WITH_ACK_RECEIPT, then on a later call to
	/// RakPeerInterface::Receive() you will get ID_SND_RECEIPT_ACKED or ID_SND_RECEIPT_LOSS. The message will be 5 bytes long,
	/// and bytes 1-4 inclusive will contain a number in native order containing a number that identifies this message. This number
	/// will be returned by RakPeerInterface::Send() or RakPeerInterface::SendList(). ID_SND_RECEIPT_LOSS means that an ack for the
	/// message did not arrive (it may or may not have been delivered, probably not). On disconnect or shutdown, you will not get
	/// ID_SND_RECEIPT_LOSS for unsent messages, you should consider those messages as all lost.
	public const ID_SND_RECEIPT_LOSS = 0x0f;


	//
	// USER TYPES - DO NOT CHANGE THESE
	//

	/// RakPeer - In a client/server environment, our connection request to the server has been accepted.
	public const ID_CONNECTION_REQUEST_ACCEPTED = 0x10;
	/// RakPeer - Sent to the player when a connection request cannot be completed due to inability to connect.
	public const ID_CONNECTION_ATTEMPT_FAILED = 0x11;
	/// RakPeer - Sent a connect request to a system we are currently connected to.
	public const ID_ALREADY_CONNECTED = 0x12;
	/// RakPeer - A remote system has successfully connected.
	public const ID_NEW_INCOMING_CONNECTION = 0x13;
	/// RakPeer - The system we attempted to connect to is not accepting new connections.
	public const ID_NO_FREE_INCOMING_CONNECTIONS = 0x14;
	/// RakPeer - The system specified in Packet::systemAddress has disconnected from us.  For the client, this would mean the
	/// server has shutdown.
	public const ID_DISCONNECTION_NOTIFICATION = 0x15;
	/// RakPeer - Reliable packets cannot be delivered to the system specified in Packet::systemAddress.  The connection to that
	/// system has been closed.
	public const ID_CONNECTION_LOST = 0x16;
	/// RakPeer - We are banned from the system we attempted to connect to.
	public const ID_CONNECTION_BANNED = 0x17;
	/// RakPeer - The remote system is using a password and has refused our connection because we did not set the correct password.
	public const ID_INVALID_PASSWORD = 0x18;
	// RAKNET_PROTOCOL_VERSION in RakNetVersion.h does not match on the remote system what we have on our system
	// This means the two systems cannot communicate.
	// The 2nd byte of the message contains the value of RAKNET_PROTOCOL_VERSION for the remote system
	public const ID_INCOMPATIBLE_PROTOCOL_VERSION = 0x19;
	// Means that this IP address connected recently, and can't connect again as a security measure. See
	/// RakPeer::SetLimitIPConnectionFrequency()
	public const ID_IP_RECENTLY_CONNECTED = 0x1a;
	/// RakPeer - The sizeof(RakNetTime) bytes following this byte represent a value which is automatically modified by the difference
	/// in system times between the sender and the recipient. Requires that you call SetOccasionalPing.
	public const ID_TIMESTAMP = 0x1b;
	/// RakPeer - Pong from an unconnected system.  First byte is ID_UNCONNECTED_PONG, second sizeof(RakNet::TimeMS) bytes is the ping,
	/// following bytes is system specific enumeration data.
	/// Read using bitstreams
	public const ID_UNCONNECTED_PONG = 0x1c;
	/// RakPeer - Inform a remote system of our IP/Port. On the recipient, all data past ID_ADVERTISE_SYSTEM is whatever was passed to
	/// the data parameter
	public const ID_ADVERTISE_SYSTEM = 0x1d;
	// RakPeer - Downloading a large message. Format is ID_DOWNLOAD_PROGRESS (MessageID), partCount (unsigned int),
	///  partTotal (unsigned int),
	/// partLength (unsigned int), first part data (length <= MAX_MTU_SIZE). See the three parameters partCount, partTotal
	///  and partLength in OnFileProgress in FileListTransferCBInterface.h
	public const ID_DOWNLOAD_PROGRESS = 0x1e;

	/// ConnectionGraph2 plugin - In a client/server environment, a client other than ourselves has disconnected gracefully.
	///   Packet::systemAddress is modified to reflect the systemAddress of this client.
	public const ID_REMOTE_DISCONNECTION_NOTIFICATION = 0x1f;
	/// ConnectionGraph2 plugin - In a client/server environment, a client other than ourselves has been forcefully dropped.
	///  Packet::systemAddress is modified to reflect the systemAddress of this client.
	public const ID_REMOTE_CONNECTION_LOST = 0x20;
	/// ConnectionGraph2 plugin: Bytes 1-4 = count. for (count items) contains {SystemAddress, RakNetGUID, 2 byte ping}
	public const ID_REMOTE_NEW_INCOMING_CONNECTION = 0x21;

	/// FileListTransfer plugin - Setup data
	public const ID_FILE_LIST_TRANSFER_HEADER = 0x22;
	/// FileListTransfer plugin - A file
	public const ID_FILE_LIST_TRANSFER_FILE = 0x23;
	// Ack for reference push, to send more of the file
	public const ID_FILE_LIST_REFERENCE_PUSH_ACK = 0x24;

	/// DirectoryDeltaTransfer plugin - Request from a remote system for a download of a directory
	public const ID_DDT_DOWNLOAD_REQUEST = 0x25;

	/// RakNetTransport plugin - Transport provider message, used for remote console
	public const ID_TRANSPORT_STRING = 0x26;

	/// ReplicaManager plugin - Create an object
	public const ID_REPLICA_MANAGER_CONSTRUCTION = 0x27;
	/// ReplicaManager plugin - Changed scope of an object
	public const ID_REPLICA_MANAGER_SCOPE_CHANGE = 0x28;
	/// ReplicaManager plugin - Serialized data of an object
	public const ID_REPLICA_MANAGER_SERIALIZE = 0x29;
	/// ReplicaManager plugin - New connection, about to send all world objects
	public const ID_REPLICA_MANAGER_DOWNLOAD_STARTED = 0x2a;
	/// ReplicaManager plugin - Finished downloading all serialized objects
	public const ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE = 0x2b;

	/// RakVoice plugin - Open a communication channel
	public const ID_RAKVOICE_OPEN_CHANNEL_REQUEST = 0x2c;
	/// RakVoice plugin - Communication channel accepted
	public const ID_RAKVOICE_OPEN_CHANNEL_REPLY = 0x2d;
	/// RakVoice plugin - Close a communication channel
	public const ID_RAKVOICE_CLOSE_CHANNEL = 0x2e;
	/// RakVoice plugin - Voice data
	public const ID_RAKVOICE_DATA = 0x2f;

	/// Autopatcher plugin - Get a list of files that have changed since a certain date
	public const ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE = 0x30;
	/// Autopatcher plugin - A list of files to create
	public const ID_AUTOPATCHER_CREATION_LIST = 0x31;
	/// Autopatcher plugin - A list of files to delete
	public const ID_AUTOPATCHER_DELETION_LIST = 0x32;
	/// Autopatcher plugin - A list of files to get patches for
	public const ID_AUTOPATCHER_GET_PATCH = 0x33;
	/// Autopatcher plugin - A list of patches for a list of files
	public const ID_AUTOPATCHER_PATCH_LIST = 0x34;
	/// Autopatcher plugin - Returned to the user: An error from the database repository for the autopatcher.
	public const ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR = 0x35;
	/// Autopatcher plugin - Returned to the user: The server does not allow downloading unmodified game files.
	public const ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES = 0x36;
	/// Autopatcher plugin - Finished getting all files from the autopatcher
	public const ID_AUTOPATCHER_FINISHED_INTERNAL = 0x37;
	public const ID_AUTOPATCHER_FINISHED = 0x38;
	/// Autopatcher plugin - Returned to the user: You must restart the application to finish patching.
	public const ID_AUTOPATCHER_RESTART_APPLICATION = 0x39;

	/// NATPunchthrough plugin: internal
	public const ID_NAT_PUNCHTHROUGH_REQUEST = 0x3a;
	/// NATPunchthrough plugin: internal
	//ID_NAT_GROUP_PUNCHTHROUGH_REQUEST,
	/// NATPunchthrough plugin: internal
	//ID_NAT_GROUP_PUNCHTHROUGH_REPLY,
	/// NATPunchthrough plugin: internal
	public const ID_NAT_CONNECT_AT_TIME = 0x3b;
	/// NATPunchthrough plugin: internal
	public const ID_NAT_GET_MOST_RECENT_PORT = 0x3c;
	/// NATPunchthrough plugin: internal
	public const ID_NAT_CLIENT_READY = 0x3d;
	/// NATPunchthrough plugin: internal
	//ID_NAT_GROUP_PUNCHTHROUGH_FAILURE_NOTIFICATION,

	/// NATPunchthrough plugin: Destination system is not connected to the server. Bytes starting at offset 1 contains the
	///  RakNetGUID destination field of NatPunchthroughClient::OpenNAT().
	public const ID_NAT_TARGET_NOT_CONNECTED = 0x3e;
	/// NATPunchthrough plugin: Destination system is not responding to ID_NAT_GET_MOST_RECENT_PORT. Possibly the plugin is not installed.
	///  Bytes starting at offset 1 contains the RakNetGUID  destination field of NatPunchthroughClient::OpenNAT().
	public const ID_NAT_TARGET_UNRESPONSIVE = 0x3f;
	/// NATPunchthrough plugin: The server lost the connection to the destination system while setting up punchthrough.
	///  Possibly the plugin is not installed. Bytes starting at offset 1 contains the RakNetGUID  destination
	///  field of NatPunchthroughClient::OpenNAT().
	public const ID_NAT_CONNECTION_TO_TARGET_LOST = 0x40;
	/// NATPunchthrough plugin: This punchthrough is already in progress. Possibly the plugin is not installed.
	///  Bytes starting at offset 1 contains the RakNetGUID destination field of NatPunchthroughClient::OpenNAT().
	public const ID_NAT_ALREADY_IN_PROGRESS = 0x41;
	/// NATPunchthrough plugin: This message is generated on the local system, and does not come from the network.
	///  packet::guid contains the destination field of NatPunchthroughClient::OpenNAT(). Byte 1 contains 1 if you are the sender, 0 if not
	public const ID_NAT_PUNCHTHROUGH_FAILED = 0x42;
	/// NATPunchthrough plugin: Punchthrough succeeded. See packet::systemAddress and packet::guid. Byte 1 contains 1 if you are the sender,
	///  0 if not. You can now use RakPeer::Connect() or other calls to communicate with this system.
	public const ID_NAT_PUNCHTHROUGH_SUCCEEDED = 0x43;

	/// ReadyEvent plugin - Set the ready state for a particular system
	/// First 4 bytes after the message contains the id
	public const ID_READY_EVENT_SET = 0x44;
	/// ReadyEvent plugin - Unset the ready state for a particular system
	/// First 4 bytes after the message contains the id
	public const ID_READY_EVENT_UNSET = 0x45;
	/// All systems are in state ID_READY_EVENT_SET
	/// First 4 bytes after the message contains the id
	public const ID_READY_EVENT_ALL_SET = 0x46;
	/// \internal, do not process in your game
	/// ReadyEvent plugin - Request of ready event state - used for pulling data when newly connecting
	public const ID_READY_EVENT_QUERY = 0x47;

	/// Lobby packets. Second byte indicates type.
	public const ID_LOBBY_GENERAL = 0x48;

	// RPC3, RPC4 error
	public const ID_RPC_REMOTE_ERROR = 0x49;
	/// Plugin based replacement for RPC system
	public const ID_RPC_PLUGIN = 0x4a;

	/// FileListTransfer transferring large files in chunks that are read only when needed, to save memory
	public const ID_FILE_LIST_REFERENCE_PUSH = 0x4b;
	/// Force the ready event to all set
	public const ID_READY_EVENT_FORCE_ALL_SET = 0x4c;

	/// Rooms function
	public const ID_ROOMS_EXECUTE_FUNC = 0x4d;
	public const ID_ROOMS_LOGON_STATUS = 0x4e;
	public const ID_ROOMS_HANDLE_CHANGE = 0x4f;

	/// Lobby2 message
	public const ID_LOBBY2_SEND_MESSAGE = 0x50;
	public const ID_LOBBY2_SERVER_ERROR = 0x51;

	/// Informs user of a new host GUID. Packet::Guid contains this new host RakNetGuid. The old host can be read out using BitStream->Read(RakNetGuid) starting on byte 1
	/// This is not returned until connected to a remote system
	/// If the oldHost is UNASSIGNED_RAKNET_GUID, then this is the first time the host has been determined
	public const ID_FCM2_NEW_HOST = 0x52;
	/// \internal For FullyConnectedMesh2 plugin
	public const ID_FCM2_REQUEST_FCMGUID = 0x53;
	/// \internal For FullyConnectedMesh2 plugin
	public const ID_FCM2_RESPOND_CONNECTION_COUNT = 0x54;
	/// \internal For FullyConnectedMesh2 plugin
	public const ID_FCM2_INFORM_FCMGUID = 0x55;
	/// \internal For FullyConnectedMesh2 plugin
	public const ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT = 0x56;
	/// A remote system (not necessarily the host) called FullyConnectedMesh2::StartVerifiedJoin() with our system as the client
	/// Use FullyConnectedMesh2::GetVerifiedJoinRequiredProcessingList() to read systems
	/// For each system, attempt NatPunchthroughClient::OpenNAT() and/or RakPeerInterface::Connect()
	/// When this has been done for all systems, the remote system will automatically be informed of the results
	/// \note Only the designated client gets this message
	/// \note You won't get this message if you are already connected to all target systems
	/// \note If you fail to connect to a system, this does not automatically mean you will get ID_FCM2_VERIFIED_JOIN_FAILED as that system may have been shutting down from the host too
	/// \sa FullyConnectedMesh2::StartVerifiedJoin()
	public const ID_FCM2_VERIFIED_JOIN_START = 0x57;
	/// \internal The client has completed processing for all systems designated in ID_FCM2_VERIFIED_JOIN_START
	public const ID_FCM2_VERIFIED_JOIN_CAPABLE = 0x58;
	/// Client failed to connect to a required systems notified via FullyConnectedMesh2::StartVerifiedJoin()
	/// RakPeerInterface::CloseConnection() was automatically called for all systems connected due to ID_FCM2_VERIFIED_JOIN_START
	/// Programmer should inform the player via the UI that they cannot join this session, and to choose a different session
	/// \note Server normally sends us this message, however if connection to the server was lost, message will be returned locally
	/// \note Only the designated client gets this message
	public const ID_FCM2_VERIFIED_JOIN_FAILED = 0x59;
	/// The system that called StartVerifiedJoin() got ID_FCM2_VERIFIED_JOIN_CAPABLE from the client and then called RespondOnVerifiedJoinCapable() with true
	/// AddParticipant() has automatically been called for this system
	/// Use GetVerifiedJoinAcceptedAdditionalData() to read any additional data passed to RespondOnVerifiedJoinCapable()
	/// \note All systems in the mesh get this message
	/// \sa RespondOnVerifiedJoinCapable()
	public const ID_FCM2_VERIFIED_JOIN_ACCEPTED = 0x5a;
	/// The system that called StartVerifiedJoin() got ID_FCM2_VERIFIED_JOIN_CAPABLE from the client and then called RespondOnVerifiedJoinCapable() with false
	/// CloseConnection() has been automatically called for each system connected to since ID_FCM2_VERIFIED_JOIN_START.
	/// The connection is NOT automatically closed to the original host that sent StartVerifiedJoin()
	/// Use GetVerifiedJoinRejectedAdditionalData() to read any additional data passed to RespondOnVerifiedJoinCapable()
	/// \note Only the designated client gets this message
	/// \sa RespondOnVerifiedJoinCapable()
	public const ID_FCM2_VERIFIED_JOIN_REJECTED = 0x5b;

	/// UDP proxy messages. Second byte indicates type.
	public const ID_UDP_PROXY_GENERAL = 0x5c;

	/// SQLite3Plugin - execute
	public const ID_SQLite3_EXEC = 0x5d;
	/// SQLite3Plugin - Remote database is unknown
	public const ID_SQLite3_UNKNOWN_DB = 0x5e;
	/// Events happening with SQLiteClientLoggerPlugin
	public const ID_SQLLITE_LOGGER = 0x5f;

	/// Sent to NatTypeDetectionServer
	public const ID_NAT_TYPE_DETECTION_REQUEST = 0x60;
	/// Sent to NatTypeDetectionClient. Byte 1 contains the type of NAT detected.
	public const ID_NAT_TYPE_DETECTION_RESULT = 0x61;

	/// Used by the router2 plugin
	public const ID_ROUTER_2_INTERNAL = 0x62;
	/// No path is available or can be established to the remote system
	/// Packet::guid contains the endpoint guid that we were trying to reach
	public const ID_ROUTER_2_FORWARDING_NO_PATH = 0x63;
	/// \brief You can now call connect, ping, or other operations to the destination system.
	///
	/// Connect as follows:
	///
	/// RakNet::BitStream bs(packet->data, packet->length, false);
	/// bs.IgnoreBytes(sizeof(MessageID));
	/// RakNetGUID endpointGuid;
	/// bs.Read(endpointGuid);
	/// unsigned short sourceToDestPort;
	/// bs.Read(sourceToDestPort);
	/// char ipAddressString[32];
	/// packet->systemAddress.ToString(false, ipAddressString);
	/// rakPeerInterface->Connect(ipAddressString, sourceToDestPort, 0,0);
	public const ID_ROUTER_2_FORWARDING_ESTABLISHED = 0x64;
	/// The IP address for a forwarded connection has changed
	/// Read endpointGuid and port as per ID_ROUTER_2_FORWARDING_ESTABLISHED
	public const ID_ROUTER_2_REROUTED = 0x65;

	/// \internal Used by the team balancer plugin
	public const ID_TEAM_BALANCER_INTERNAL = 0x66;
	/// Cannot switch to the desired team because it is full. However, if someone on that team leaves, you will
	///  get ID_TEAM_BALANCER_TEAM_ASSIGNED later.
	/// For TeamBalancer: Byte 1 contains the team you requested to join. Following bytes contain NetworkID of which member
	public const ID_TEAM_BALANCER_REQUESTED_TEAM_FULL = 0x67;
	/// Cannot switch to the desired team because all teams are locked. However, if someone on that team leaves,
	///  you will get ID_TEAM_BALANCER_SET_TEAM later.
	/// For TeamBalancer: Byte 1 contains the team you requested to join.
	public const ID_TEAM_BALANCER_REQUESTED_TEAM_LOCKED = 0x68;
	public const ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED = 0x69;
	/// Team balancer plugin informing you of your team. Byte 1 contains the team you requested to join. Following bytes contain NetworkID of which member.
	public const ID_TEAM_BALANCER_TEAM_ASSIGNED = 0x6a;

	/// Gamebryo Lightspeed integration
	public const ID_LIGHTSPEED_INTEGRATION = 0x6b;

	/// XBOX integration
	public const ID_XBOX_LOBBY = 0x6c;

	/// The password we used to challenge the other system passed, meaning the other system has called TwoWayAuthentication::AddPassword() with the same password we passed to TwoWayAuthentication::Challenge()
	/// You can read the identifier used to challenge as follows:
	/// RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(RakNet::MessageID)); RakNet::RakString password; bs.Read(password);
	public const ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS = 0x6d;
	public const ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS = 0x6e;
	/// A remote system sent us a challenge using TwoWayAuthentication::Challenge(), and the challenge failed.
	/// If the other system must pass the challenge to stay connected, you should call RakPeer::CloseConnection() to terminate the connection to the other system.
	public const ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE = 0x6f;
	/// The other system did not add the password we used to TwoWayAuthentication::AddPassword()
	/// You can read the identifier used to challenge as follows:
	/// RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); RakNet::RakString password; bs.Read(password);
	public const ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE = 0x70;
	/// The other system did not respond within a timeout threshhold. Either the other system is not running the plugin or the other system was blocking on some operation for a long time.
	/// You can read the identifier used to challenge as follows:
	/// RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); RakNet::RakString password; bs.Read(password);
	public const ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT = 0x71;
	/// \internal
	public const ID_TWO_WAY_AUTHENTICATION_NEGOTIATION = 0x72;

	/// CloudClient / CloudServer
	public const ID_CLOUD_POST_REQUEST = 0x73;
	public const ID_CLOUD_RELEASE_REQUEST = 0x74;
	public const ID_CLOUD_GET_REQUEST = 0x75;
	public const ID_CLOUD_GET_RESPONSE = 0x76;
	public const ID_CLOUD_UNSUBSCRIBE_REQUEST = 0x77;
	public const ID_CLOUD_SERVER_TO_SERVER_COMMAND = 0x78;
	public const ID_CLOUD_SUBSCRIPTION_NOTIFICATION = 0x79;

	// LibVoice
	public const ID_LIB_VOICE = 0x7a;

	public const ID_RELAY_PLUGIN = 0x7b;
	public const ID_NAT_REQUEST_BOUND_ADDRESSES = 0x7c;
	public const ID_NAT_RESPOND_BOUND_ADDRESSES = 0x7d;
	public const ID_FCM2_UPDATE_USER_CONTEXT = 0x7e;
	public const ID_RESERVED_3 = 0x7f;
	public const ID_RESERVED_4 = 0x80;
	public const ID_RESERVED_5 = 0x81;
	public const ID_RESERVED_6 = 0x82;
	public const ID_RESERVED_7 = 0x83;
	public const ID_RESERVED_8 = 0x84;
	public const ID_RESERVED_9 = 0x85;

	// For the user to use.  Start your first enumeration at this value.
	public const ID_USER_PACKET_ENUM = 0x86;
	//-------------------------------------------------------------------------------------------------------------
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;


class UnconnectedPingOpenConnections extends UnconnectedPing{
	public static $ID = MessageIdentifiers::ID_UNCONNECTED_PING_OPEN_CONNECTIONS;
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;


use raklib\RakLib;
use function str_pad;
use function strlen;

class OpenConnectionRequest1 extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REQUEST_1;

	/** @var int */
	public $protocol = RakLib::DEFAULT_PROTOCOL_VERSION;
	/** @var int */
	public $mtuSize;

	protected function encodePayload() : void{
		$this->writeMagic();
		($this->buffer .= \chr($this->protocol));
		$this->buffer = str_pad($this->buffer, $this->mtuSize, "\x00");
	}

	protected function decodePayload() : void{
		$this->readMagic();
		$this->protocol = (\ord($this->get(1)));
		$this->mtuSize = strlen($this->buffer);
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib;

use function defined;
use function extension_loaded;
use function phpversion;
use function substr_count;
use function version_compare;
use const PHP_EOL;
use const PHP_VERSION;

//Dependencies check
$errors = 0;
if(version_compare(RakLib::MIN_PHP_VERSION, PHP_VERSION) > 0){
	echo "[CRITICAL] Use PHP >= " . RakLib::MIN_PHP_VERSION . PHP_EOL;
	++$errors;
}

$exts = [
	"bcmath" => "BC Math",
	"pthreads" => "pthreads",
	"sockets" => "Sockets"
];

foreach($exts as $ext => $name){
	if(!extension_loaded($ext)){
		echo "[CRITICAL] Unable to find the $name ($ext) extension." . PHP_EOL;
		++$errors;
	}
}

if(extension_loaded("pthreads")){
	$pthreads_version = phpversion("pthreads");
	if(substr_count($pthreads_version, ".") < 2){
		$pthreads_version = "0.$pthreads_version";
	}

	if(version_compare($pthreads_version, "3.1.7dev") < 0){
		echo "[CRITICAL] pthreads >= 3.1.7dev is required, while you have $pthreads_version.";
		++$errors;
	}
}

if(!defined('AF_INET6')){
	echo "[CRITICAL] This build of PHP does not support IPv6. IPv6 support is required.";
	++$errors;
}

if($errors > 0){
	exit(1); //Exit with error
}
unset($errors, $exts);

abstract class RakLib{
	public const VERSION = "0.12.0";

	public const MIN_PHP_VERSION = "7.2.0";

	/**
	 * Default vanilla Raknet protocol version that this library implements. Things using RakNet can override this
	 * protocol version with something different.
	 */
	public const DEFAULT_PROTOCOL_VERSION = 6;
	public const MAGIC = "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78";

	public const PRIORITY_NORMAL = 0;
	public const PRIORITY_IMMEDIATE = 1;

	public const FLAG_NEED_ACK = 0b00001000;

	/*
	 * These internal "packets" DO NOT exist in the RakNet protocol. They are used by the RakLib API to communicate
	 * messages between the RakLib thread and the implementation's thread.
	 *
	 * Internal Packet:
	 * int32 (length without this field)
	 * byte (packet ID)
	 * payload
	 */

	/*
	 * ENCAPSULATED payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 * byte (flags, last 3 bits, priority)
	 * payload (binary internal EncapsulatedPacket)
	 */
	public const PACKET_ENCAPSULATED = 0x01;

	/*
	 * OPEN_SESSION payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 * byte (address length)
	 * byte[] (address)
	 * short (port)
	 * long (clientID)
	 */
	public const PACKET_OPEN_SESSION = 0x02;

	/*
	 * CLOSE_SESSION payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 * string (reason)
	 */
	public const PACKET_CLOSE_SESSION = 0x03;

	/*
	 * INVALID_SESSION payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 */
	public const PACKET_INVALID_SESSION = 0x04;

	/* TODO: implement this
	 * SEND_QUEUE payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 */
	public const PACKET_SEND_QUEUE = 0x05;

	/*
	 * ACK_NOTIFICATION payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 * int (identifierACK)
	 */
	public const PACKET_ACK_NOTIFICATION = 0x06;

	/*
	 * SET_OPTION payload:
	 * byte (option name length)
	 * byte[] (option name)
	 * byte[] (option value)
	 */
	public const PACKET_SET_OPTION = 0x07;

	/*
	 * RAW payload:
	 * byte (address length)
	 * byte[] (address from/to)
	 * short (port)
	 * byte[] (payload)
	 */
	public const PACKET_RAW = 0x08;

	/*
	 * BLOCK_ADDRESS payload:
	 * byte (address length)
	 * byte[] (address)
	 * int (timeout)
	 */
	public const PACKET_BLOCK_ADDRESS = 0x09;

	/*
	 * UNBLOCK_ADDRESS payload:
	 * byte (address length)
	 * byte[] (address)
	 */
	public const PACKET_UNBLOCK_ADDRESS = 0x10;

	/*
	 * REPORT_PING payload:
	 * byte (identifier length)
	 * byte[] (identifier)
	 * int32 (measured latency in MS)
	 */
	public const PACKET_REPORT_PING = 0x11;

	/*
	 * No payload
	 *
	 * Sends the disconnect message, removes sessions correctly, closes sockets.
	 */
	public const PACKET_SHUTDOWN = 0x7e;

	/*
	 * No payload
	 *
	 * Leaves everything as-is and halts, other Threads can be in a post-crash condition.
	 */
	public const PACKET_EMERGENCY_SHUTDOWN = 0x7f;

	/**
	 * Regular RakNet uses 10 by default. MCPE uses 20. Configure this value as appropriate.
	 * @var int
	 */
	public static $SYSTEM_ADDRESS_COUNT = 20;
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class OpenConnectionReply1 extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REPLY_1;

	/** @var int */
	public $serverID;
	/** @var bool */
	public $serverSecurity = false;
	/** @var int */
	public $mtuSize;

	protected function encodePayload() : void{
		$this->writeMagic();
		($this->buffer .= (\pack("NN", $this->serverID >> 32, $this->serverID & 0xFFFFFFFF)));
		($this->buffer .= \chr($this->serverSecurity ? 1 : 0));
		($this->buffer .= (\pack("n", $this->mtuSize)));
	}

	protected function decodePayload() : void{
		$this->readMagic();
		$this->serverID = (Binary::readLong($this->get(8)));
		$this->serverSecurity = (\ord($this->get(1))) !== 0;
		$this->mtuSize = ((\unpack("n", $this->get(2))[1]));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

use raklib\utils\InternetAddress;

class OpenConnectionRequest2 extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REQUEST_2;

	/** @var int */
	public $clientID;
	/** @var InternetAddress */
	public $serverAddress;
	/** @var int */
	public $mtuSize;

	protected function encodePayload() : void{
		$this->writeMagic();
		$this->putAddress($this->serverAddress);
		($this->buffer .= (\pack("n", $this->mtuSize)));
		($this->buffer .= (\pack("NN", $this->clientID >> 32, $this->clientID & 0xFFFFFFFF)));
	}

	protected function decodePayload() : void{
		$this->readMagic();
		$this->serverAddress = $this->getAddress();
		$this->mtuSize = ((\unpack("n", $this->get(2))[1]));
		$this->clientID = (Binary::readLong($this->get(8)));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

use raklib\utils\InternetAddress;

class OpenConnectionReply2 extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REPLY_2;

	/** @var int */
	public $serverID;
	/** @var InternetAddress */
	public $clientAddress;
	/** @var int */
	public $mtuSize;
	/** @var bool */
	public $serverSecurity = false;

	protected function encodePayload() : void{
		$this->writeMagic();
		($this->buffer .= (\pack("NN", $this->serverID >> 32, $this->serverID & 0xFFFFFFFF)));
		$this->putAddress($this->clientAddress);
		($this->buffer .= (\pack("n", $this->mtuSize)));
		($this->buffer .= \chr($this->serverSecurity ? 1 : 0));
	}

	protected function decodePayload() : void{
		$this->readMagic();
		$this->serverID = (Binary::readLong($this->get(8)));
		$this->clientAddress = $this->getAddress();
		$this->mtuSize = ((\unpack("n", $this->get(2))[1]));
		$this->serverSecurity = (\ord($this->get(1))) !== 0;
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class UnconnectedPong extends OfflineMessage{
	public static $ID = MessageIdentifiers::ID_UNCONNECTED_PONG;

	/** @var int */
	public $pingID;
	/** @var int */
	public $serverID;
	/** @var string */
	public $serverName;

	protected function encodePayload() : void{
		($this->buffer .= (\pack("NN", $this->pingID >> 32, $this->pingID & 0xFFFFFFFF)));
		($this->buffer .= (\pack("NN", $this->serverID >> 32, $this->serverID & 0xFFFFFFFF)));
		$this->writeMagic();
		$this->putString($this->serverName);
	}

	protected function decodePayload() : void{
		$this->pingID = (Binary::readLong($this->get(8)));
		$this->serverID = (Binary::readLong($this->get(8)));
		$this->readMagic();
		$this->serverName = $this->getString();
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

class AdvertiseSystem extends Packet{
	public static $ID = MessageIdentifiers::ID_ADVERTISE_SYSTEM;

	/** @var string */
	public $serverName;

	protected function encodePayload() : void{
		$this->putString($this->serverName);
	}

	protected function decodePayload() : void{
		$this->serverName = $this->getString();
	}
}
<?php

/*
 *
 *  ____            _        _   __  __ _                  __  __ ____
 * |  _ \ ___   ___| | _____| |_|  \/  (_)_ __   ___      |  \/  |  _ \
 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
 * |  __/ (_) | (__|   <  __/ |_| |  | | | | | |  __/_____| |  | |  __/
 * |_|   \___/ \___|_|\_\___|\__|_|  |_|_|_| |_|\___|     |_|  |_|_|
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @author PocketMine Team
 * @link http://www.pocketmine.net/
 *
 *
*/

declare(strict_types=1);

/**
 * Methods for working with binary strings
 */
namespace pocketmine\utils;

use InvalidArgumentException;
use function chr;
use function define;
use function defined;
use function ord;
use function pack;
use function preg_replace;
use function round;
use function sprintf;
use function substr;
use function unpack;
use const PHP_INT_MAX;

if(!defined("ENDIANNESS")){
	define("ENDIANNESS", (pack("s", 1) === "\0\1" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN));
}

class Binary{
	public const BIG_ENDIAN = 0x00;
	public const LITTLE_ENDIAN = 0x01;

	public static function signByte(int $value) : int{
		return $value << 56 >> 56;
	}

	public static function unsignByte(int $value) : int{
		return $value & 0xff;
	}

	public static function signShort(int $value) : int{
		return $value << 48 >> 48;
	}

	public static function unsignShort(int $value) : int{
		return $value & 0xffff;
	}

	public static function signInt(int $value) : int{
		return $value << 32 >> 32;
	}

	public static function unsignInt(int $value) : int{
		return $value & 0xffffffff;
	}


	public static function flipShortEndianness(int $value) : int{
		return self::readLShort(self::writeShort($value));
	}

	public static function flipIntEndianness(int $value) : int{
		return self::readLInt(self::writeInt($value));
	}

	public static function flipLongEndianness(int $value) : int{
		return self::readLLong(self::writeLong($value));
	}

	/**
	 * Reads a byte boolean
	 *
	 * @param string $b
	 *
	 * @return bool
	 */
	public static function readBool(string $b) : bool{
		return $b !== "\x00";
	}

	/**
	 * Writes a byte boolean
	 *
	 * @param bool $b
	 *
	 * @return string
	 */
	public static function writeBool(bool $b) : string{
		return $b ? "\x01" : "\x00";
	}

	/**
	 * Reads an unsigned byte (0 - 255)
	 *
	 * @param string $c
	 *
	 * @return int
	 */
	public static function readByte(string $c) : int{
		return ord($c[0]);
	}

	/**
	 * Reads a signed byte (-128 - 127)
	 *
	 * @param string $c
	 *
	 * @return int
	 */
	public static function readSignedByte(string $c) : int{
		return self::signByte(ord($c[0]));
	}

	/**
	 * Writes an unsigned/signed byte
	 *
	 * @param int $c
	 *
	 * @return string
	 */
	public static function writeByte(int $c) : string{
		return chr($c);
	}

	/**
	 * Reads a 16-bit unsigned big-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readShort(string $str) : int{
		return unpack("n", $str)[1];
	}

	/**
	 * Reads a 16-bit signed big-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readSignedShort(string $str) : int{
		return self::signShort(unpack("n", $str)[1]);
	}

	/**
	 * Writes a 16-bit signed/unsigned big-endian number
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeShort(int $value) : string{
		return pack("n", $value);
	}

	/**
	 * Reads a 16-bit unsigned little-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readLShort(string $str) : int{
		return unpack("v", $str)[1];
	}

	/**
	 * Reads a 16-bit signed little-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readSignedLShort(string $str) : int{
		return self::signShort(unpack("v", $str)[1]);
	}

	/**
	 * Writes a 16-bit signed/unsigned little-endian number
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeLShort(int $value) : string{
		return pack("v", $value);
	}

	/**
	 * Reads a 3-byte big-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readTriad(string $str) : int{
		return unpack("N", "\x00" . $str)[1];
	}

	/**
	 * Writes a 3-byte big-endian number
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeTriad(int $value) : string{
		return substr(pack("N", $value), 1);
	}

	/**
	 * Reads a 3-byte little-endian number
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readLTriad(string $str) : int{
		return unpack("V", $str . "\x00")[1];
	}

	/**
	 * Writes a 3-byte little-endian number
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeLTriad(int $value) : string{
		return substr(pack("V", $value), 0, -1);
	}

	/**
	 * Reads a 4-byte signed integer
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readInt(string $str) : int{
		return self::signInt(unpack("N", $str)[1]);
	}

	/**
	 * Writes a 4-byte integer
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeInt(int $value) : string{
		return pack("N", $value);
	}

	/**
	 * Reads a 4-byte signed little-endian integer
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readLInt(string $str) : int{
		return self::signInt(unpack("V", $str)[1]);
	}

	/**
	 * Writes a 4-byte signed little-endian integer
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeLInt(int $value) : string{
		return pack("V", $value);
	}

	/**
	 * Reads a 4-byte floating-point number
	 *
	 * @param string $str
	 *
	 * @return float
	 */
	public static function readFloat(string $str) : float{
		return unpack("G", $str)[1];
	}

	/**
	 * Reads a 4-byte floating-point number, rounded to the specified number of decimal places.
	 *
	 * @param string $str
	 * @param int    $accuracy
	 *
	 * @return float
	 */
	public static function readRoundedFloat(string $str, int $accuracy) : float{
		return round(self::readFloat($str), $accuracy);
	}

	/**
	 * Writes a 4-byte floating-point number.
	 *
	 * @param float $value
	 *
	 * @return string
	 */
	public static function writeFloat(float $value) : string{
		return pack("G", $value);
	}

	/**
	 * Reads a 4-byte little-endian floating-point number.
	 *
	 * @param string $str
	 *
	 * @return float
	 */
	public static function readLFloat(string $str) : float{
		return unpack("g", $str)[1];
	}

	/**
	 * Reads a 4-byte little-endian floating-point number rounded to the specified number of decimal places.
	 *
	 * @param string $str
	 * @param int    $accuracy
	 *
	 * @return float
	 */
	public static function readRoundedLFloat(string $str, int $accuracy) : float{
		return round(self::readLFloat($str), $accuracy);
	}

	/**
	 * Writes a 4-byte little-endian floating-point number.
	 *
	 * @param float $value
	 *
	 * @return string
	 */
	public static function writeLFloat(float $value) : string{
		return pack("g", $value);
	}

	/**
	 * Returns a printable floating-point number.
	 *
	 * @param float $value
	 *
	 * @return string
	 */
	public static function printFloat(float $value) : string{
		return preg_replace("/(\\.\\d+?)0+$/", "$1", sprintf("%F", $value));
	}

	/**
	 * Reads an 8-byte floating-point number.
	 *
	 * @param string $str
	 *
	 * @return float
	 */
	public static function readDouble(string $str) : float{
		return unpack("E", $str)[1];
	}

	/**
	 * Writes an 8-byte floating-point number.
	 *
	 * @param float $value
	 *
	 * @return string
	 */
	public static function writeDouble(float $value) : string{
		return pack("E", $value);
	}

	/**
	 * Reads an 8-byte little-endian floating-point number.
	 *
	 * @param string $str
	 *
	 * @return float
	 */
	public static function readLDouble(string $str) : float{
		return unpack("e", $str)[1];
	}

	/**
	 * Writes an 8-byte floating-point little-endian number.
	 *
	 * @param float $value
	 *
	 * @return string
	 */
	public static function writeLDouble(float $value) : string{
		return pack("e", $value);
	}

	/**
	 * Reads an 8-byte integer.
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readLong(string $str) : int{
		return unpack("J", $str)[1];
	}

	/**
	 * Writes an 8-byte integer.
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeLong(int $value) : string{
		return pack("J", $value);
	}

	/**
	 * Reads an 8-byte little-endian integer.
	 *
	 * @param string $str
	 *
	 * @return int
	 */
	public static function readLLong(string $str) : int{
		return unpack("P", $str)[1];
	}

	/**
	 * Writes an 8-byte little-endian integer.
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeLLong(int $value) : string{
		return pack("P", $value);
	}


	/**
	 * Reads a 32-bit zigzag-encoded variable-length integer.
	 *
	 * @param string $buffer
	 * @param int    $offset reference parameter
	 *
	 * @return int
	 */
	public static function readVarInt(string $buffer, int &$offset) : int{
		$raw = self::readUnsignedVarInt($buffer, $offset);
		$temp = ((($raw << 63) >> 63) ^ $raw) >> 1;
		return $temp ^ ($raw & (1 << 63));
	}

	/**
	 * Reads a 32-bit variable-length unsigned integer.
	 *
	 * @param string $buffer
	 * @param int    $offset reference parameter
	 *
	 * @return int
	 *
	 * @throws BinaryDataException if the var-int did not end after 5 bytes or there were not enough bytes
	 */
	public static function readUnsignedVarInt(string $buffer, int &$offset) : int{
		$value = 0;
		for($i = 0; $i <= 28; $i += 7){
			if(!isset($buffer[$offset])){
				throw new BinaryDataException("No bytes left in buffer");
			}
			$b = ord($buffer[$offset++]);
			$value |= (($b & 0x7f) << $i);

			if(($b & 0x80) === 0){
				return $value;
			}
		}

		throw new BinaryDataException("VarInt did not terminate after 5 bytes!");
	}

	/**
	 * Writes a 32-bit integer as a zigzag-encoded variable-length integer.
	 *
	 * @param int $v
	 *
	 * @return string
	 */
	public static function writeVarInt(int $v) : string{
		$v = ($v << 32 >> 32);
		return self::writeUnsignedVarInt(($v << 1) ^ ($v >> 31));
	}

	/**
	 * Writes a 32-bit unsigned integer as a variable-length integer.
	 *
	 * @param int $value
	 *
	 * @return string up to 5 bytes
	 */
	public static function writeUnsignedVarInt(int $value) : string{
		$buf = "";
		$value &= 0xffffffff;
		for($i = 0; $i < 5; ++$i){
			if(($value >> 7) !== 0){
				$buf .= chr($value | 0x80);
			}else{
				$buf .= chr($value & 0x7f);
				return $buf;
			}

			$value = (($value >> 7) & (PHP_INT_MAX >> 6)); //PHP really needs a logical right-shift operator
		}

		throw new InvalidArgumentException("Value too large to be encoded as a VarInt");
	}


	/**
	 * Reads a 64-bit zigzag-encoded variable-length integer.
	 *
	 * @param string $buffer
	 * @param int    $offset reference parameter
	 *
	 * @return int
	 */
	public static function readVarLong(string $buffer, int &$offset) : int{
		$raw = self::readUnsignedVarLong($buffer, $offset);
		$temp = ((($raw << 63) >> 63) ^ $raw) >> 1;
		return $temp ^ ($raw & (1 << 63));
	}

	/**
	 * Reads a 64-bit unsigned variable-length integer.
	 *
	 * @param string $buffer
	 * @param int    $offset reference parameter
	 *
	 * @return int
	 *
	 * @throws BinaryDataException if the var-int did not end after 10 bytes or there were not enough bytes
	 */
	public static function readUnsignedVarLong(string $buffer, int &$offset) : int{
		$value = 0;
		for($i = 0; $i <= 63; $i += 7){
			if(!isset($buffer[$offset])){
				throw new BinaryDataException("No bytes left in buffer");
			}
			$b = ord($buffer[$offset++]);
			$value |= (($b & 0x7f) << $i);

			if(($b & 0x80) === 0){
				return $value;
			}
		}

		throw new BinaryDataException("VarLong did not terminate after 10 bytes!");
	}

	/**
	 * Writes a 64-bit integer as a zigzag-encoded variable-length long.
	 *
	 * @param int $v
	 *
	 * @return string
	 */
	public static function writeVarLong(int $v) : string{
		return self::writeUnsignedVarLong(($v << 1) ^ ($v >> 63));
	}

	/**
	 * Writes a 64-bit unsigned integer as a variable-length long.
	 *
	 * @param int $value
	 *
	 * @return string
	 */
	public static function writeUnsignedVarLong(int $value) : string{
		$buf = "";
		for($i = 0; $i < 10; ++$i){
			if(($value >> 7) !== 0){
				$buf .= chr($value | 0x80); //Let chr() take the last byte of this, it's faster than adding another & 0x7f.
			}else{
				$buf .= chr($value & 0x7f);
				return $buf;
			}

			$value = (($value >> 7) & (PHP_INT_MAX >> 6)); //PHP really needs a logical right-shift operator
		}

		throw new InvalidArgumentException("Value too large to be encoded as a VarLong");
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\server;

use raklib\protocol\ACK;
use raklib\protocol\ConnectedPing;
use raklib\protocol\ConnectedPong;
use raklib\protocol\ConnectionRequest;
use raklib\protocol\ConnectionRequestAccepted;
use raklib\protocol\Datagram;
use raklib\protocol\DisconnectionNotification;
use raklib\protocol\EncapsulatedPacket;
use raklib\protocol\MessageIdentifiers;
use raklib\protocol\NACK;
use raklib\protocol\NewIncomingConnection;
use raklib\protocol\Packet;
use raklib\protocol\PacketReliability;
use raklib\RakLib;
use raklib\utils\InternetAddress;
use function array_fill;
use function assert;
use function count;
use function microtime;
use function ord;
use function str_split;
use function strlen;
use function time;

class Session{
	public const STATE_CONNECTING = 0;
	public const STATE_CONNECTED = 1;
	public const STATE_DISCONNECTING = 2;
	public const STATE_DISCONNECTED = 3;

	public const MIN_MTU_SIZE = 400;

	private const MAX_SPLIT_SIZE = 128;
	private const MAX_SPLIT_COUNT = 4;

	private const CHANNEL_COUNT = 32;

	public static $WINDOW_SIZE = 2048;

	/** @var int */
	private $messageIndex = 0;

	/** @var int[] */
	private $sendOrderedIndex;
	/** @var int[] */
	private $sendSequencedIndex;
	/** @var int[] */
	private $receiveOrderedIndex;
	/** @var int[] */
	private $receiveSequencedHighestIndex;
	/** @var EncapsulatedPacket[][] */
	private $receiveOrderedPackets;

	/** @var SessionManager */
	private $sessionManager;

	/** @var InternetAddress */
	private $address;

	/** @var int */
	private $state = self::STATE_CONNECTING;
	/** @var int */
	private $mtuSize;
	/** @var int */
	private $id;
	/** @var int */
	private $splitID = 0;

	/** @var int */
	private $sendSeqNumber = 0;

	/** @var float */
	private $lastUpdate;
	/** @var float|null */
	private $disconnectionTime;

	/** @var bool */
	private $isTemporal = true;

	/** @var Datagram[] */
	private $packetToSend = [];
	/** @var bool */
	private $isActive = false;

	/** @var int[] */
	private $ACKQueue = [];
	/** @var int[] */
	private $NACKQueue = [];

	/** @var Datagram[] */
	private $recoveryQueue = [];

	/** @var (EncapsulatedPacket|null)[][] */
	private $splitPackets = [];

	/** @var int[][] */
	private $needACK = [];

	/** @var Datagram */
	private $sendQueue;

	/** @var int */
	private $windowStart;
	/** @var int */
	private $windowEnd;
	/** @var int */
	private $highestSeqNumberThisTick = -1;

	/** @var int */
	private $reliableWindowStart;
	/** @var int */
	private $reliableWindowEnd;
	/** @var bool[] */
	private $reliableWindow = [];

	/** @var float */
	private $lastPingTime = -1;
	/** @var int */
	private $lastPingMeasure = 1;

	public function __construct(SessionManager $sessionManager, InternetAddress $address, int $clientId, int $mtuSize){
		if($mtuSize < self::MIN_MTU_SIZE){
			throw new \InvalidArgumentException("MTU size must be at least " . self::MIN_MTU_SIZE . ", got $mtuSize");
		}
		$this->sessionManager = $sessionManager;
		$this->address = $address;
		$this->id = $clientId;
		$this->sendQueue = new Datagram();

		$this->lastUpdate = microtime(true);
		$this->windowStart = 0;
		$this->windowEnd = self::$WINDOW_SIZE;

		$this->reliableWindowStart = 0;
		$this->reliableWindowEnd = self::$WINDOW_SIZE;

		$this->sendOrderedIndex = array_fill(0, self::CHANNEL_COUNT, 0);
		$this->sendSequencedIndex = array_fill(0, self::CHANNEL_COUNT, 0);

		$this->receiveOrderedIndex = array_fill(0, self::CHANNEL_COUNT, 0);
		$this->receiveSequencedHighestIndex = array_fill(0, self::CHANNEL_COUNT, 0);

		$this->receiveOrderedPackets = array_fill(0, self::CHANNEL_COUNT, []);

		$this->mtuSize = $mtuSize;
	}

	public function getAddress() : InternetAddress{
		return $this->address;
	}

	public function getID() : int{
		return $this->id;
	}

	public function getState() : int{
		return $this->state;
	}

	public function isTemporal() : bool{
		return $this->isTemporal;
	}

	public function isConnected() : bool{
		return $this->state !== self::STATE_DISCONNECTING and $this->state !== self::STATE_DISCONNECTED;
	}

	public function update(float $time) : void{
		if(!$this->isActive and ($this->lastUpdate + 10) < $time){
			$this->disconnect("timeout");

			return;
		}

		if($this->state === self::STATE_DISCONNECTING and (
			(empty($this->ACKQueue) and empty($this->NACKQueue) and empty($this->packetToSend) and empty($this->recoveryQueue)) or
			$this->disconnectionTime + 10 < $time)
		){
			$this->close();
			return;
		}

		$this->isActive = false;

		$diff = $this->highestSeqNumberThisTick - $this->windowStart + 1;
		assert($diff >= 0);
		if($diff > 0){
			//Move the receive window to account for packets we either received or are about to NACK
			//we ignore any sequence numbers that we sent NACKs for, because we expect the client to resend them
			//when it gets a NACK for it

			$this->windowStart += $diff;
			$this->windowEnd += $diff;
		}

		if(count($this->ACKQueue) > 0){
			$pk = new ACK();
			$pk->packets = $this->ACKQueue;
			$this->sendPacket($pk);
			$this->ACKQueue = [];
		}

		if(count($this->NACKQueue) > 0){
			$pk = new NACK();
			$pk->packets = $this->NACKQueue;
			$this->sendPacket($pk);
			$this->NACKQueue = [];
		}

		if(count($this->packetToSend) > 0){
			$limit = 16;
			foreach($this->packetToSend as $k => $pk){
				$this->sendDatagram($pk);
				unset($this->packetToSend[$k]);

				if(--$limit <= 0){
					break;
				}
			}

			if(count($this->packetToSend) > self::$WINDOW_SIZE){
				$this->packetToSend = [];
			}
		}

		if(count($this->needACK) > 0){
			foreach($this->needACK as $identifierACK => $indexes){
				if(count($indexes) === 0){
					unset($this->needACK[$identifierACK]);
					$this->sessionManager->notifyACK($this, $identifierACK);
				}
			}
		}


		foreach($this->recoveryQueue as $seq => $pk){
			if($pk->sendTime < (time() - 8)){
				$this->packetToSend[] = $pk;
				unset($this->recoveryQueue[$seq]);
			}else{
				break;
			}
		}

		if($this->lastPingTime + 5 < $time){
			$this->sendPing();
			$this->lastPingTime = $time;
		}

		$this->sendQueue();
	}

	public function disconnect(string $reason = "unknown") : void{
		$this->sessionManager->removeSession($this, $reason);
	}

	private function sendDatagram(Datagram $datagram) : void{
		if($datagram->seqNumber !== null){
			unset($this->recoveryQueue[$datagram->seqNumber]);
		}
		$datagram->seqNumber = $this->sendSeqNumber++;
		$datagram->sendTime = microtime(true);
		$this->recoveryQueue[$datagram->seqNumber] = $datagram;
		$this->sendPacket($datagram);
	}

	private function queueConnectedPacket(Packet $packet, int $reliability, int $orderChannel, int $flags = RakLib::PRIORITY_NORMAL) : void{
		$packet->encode();

		$encapsulated = new EncapsulatedPacket();
		$encapsulated->reliability = $reliability;
		$encapsulated->orderChannel = $orderChannel;
		$encapsulated->buffer = $packet->getBuffer();

		$this->addEncapsulatedToQueue($encapsulated, $flags);
	}

	private function sendPacket(Packet $packet) : void{
		$this->sessionManager->sendPacket($packet, $this->address);
	}

	public function sendQueue() : void{
		if(count($this->sendQueue->packets) > 0){
			$this->sendDatagram($this->sendQueue);
			$this->sendQueue = new Datagram();
		}
	}

	private function sendPing(int $reliability = PacketReliability::UNRELIABLE) : void{
		$pk = new ConnectedPing();
		$pk->sendPingTime = $this->sessionManager->getRakNetTimeMS();
		$this->queueConnectedPacket($pk, $reliability, 0, RakLib::PRIORITY_IMMEDIATE);
	}

	/**
	 * @param EncapsulatedPacket $pk
	 * @param int                $flags
	 */
	private function addToQueue(EncapsulatedPacket $pk, int $flags = RakLib::PRIORITY_NORMAL) : void{
		$priority = $flags & 0b00000111;
		if($pk->needACK and $pk->messageIndex !== null){
			$this->needACK[$pk->identifierACK][$pk->messageIndex] = $pk->messageIndex;
		}

		$length = $this->sendQueue->length();
		if($length + $pk->getTotalLength() > $this->mtuSize - 36){ //IP header (20 bytes) + UDP header (8 bytes) + RakNet weird (8 bytes) = 36 bytes
			$this->sendQueue();
		}

		if($pk->needACK){
			$this->sendQueue->packets[] = clone $pk;
			$pk->needACK = false;
		}else{
			$this->sendQueue->packets[] = $pk->toBinary();
		}

		if($priority === RakLib::PRIORITY_IMMEDIATE){
			// Forces pending sends to go out now, rather than waiting to the next update interval
			$this->sendQueue();
		}
	}

	/**
	 * @param EncapsulatedPacket $packet
	 * @param int                $flags
	 */
	public function addEncapsulatedToQueue(EncapsulatedPacket $packet, int $flags = RakLib::PRIORITY_NORMAL) : void{

		if(($packet->needACK = ($flags & RakLib::FLAG_NEED_ACK) > 0) === true){
			$this->needACK[$packet->identifierACK] = [];
		}

		if(PacketReliability::isOrdered($packet->reliability)){
			$packet->orderIndex = $this->sendOrderedIndex[$packet->orderChannel]++;
		}elseif(PacketReliability::isSequenced($packet->reliability)){
			$packet->orderIndex = $this->sendOrderedIndex[$packet->orderChannel]; //sequenced packets don't increment the ordered channel index
			$packet->sequenceIndex = $this->sendSequencedIndex[$packet->orderChannel]++;
		}

		//IP header size (20 bytes) + UDP header size (8 bytes) + RakNet weird (8 bytes) + datagram header size (4 bytes) + max encapsulated packet header size (20 bytes)
		$maxSize = $this->mtuSize - 60;

		if(strlen($packet->buffer) > $maxSize){
			$buffers = str_split($packet->buffer, $maxSize);
			$bufferCount = count($buffers);

			$splitID = ++$this->splitID % 65536;
			foreach($buffers as $count => $buffer){
				$pk = new EncapsulatedPacket();
				$pk->splitID = $splitID;
				$pk->hasSplit = true;
				$pk->splitCount = $bufferCount;
				$pk->reliability = $packet->reliability;
				$pk->splitIndex = $count;
				$pk->buffer = $buffer;

				if(PacketReliability::isReliable($pk->reliability)){
					$pk->messageIndex = $this->messageIndex++;
				}

				$pk->sequenceIndex = $packet->sequenceIndex;
				$pk->orderChannel = $packet->orderChannel;
				$pk->orderIndex = $packet->orderIndex;

				$this->addToQueue($pk, $flags | RakLib::PRIORITY_IMMEDIATE);
			}
		}else{
			if(PacketReliability::isReliable($packet->reliability)){
				$packet->messageIndex = $this->messageIndex++;
			}
			$this->addToQueue($packet, $flags);
		}
	}

	/**
	 * Processes a split part of an encapsulated packet.
	 *
	 * @param EncapsulatedPacket $packet
	 *
	 * @return null|EncapsulatedPacket Reassembled packet if we have all the parts, null otherwise.
	 */
	private function handleSplit(EncapsulatedPacket $packet) : ?EncapsulatedPacket{
		if(
			$packet->splitCount >= self::MAX_SPLIT_SIZE or $packet->splitCount < 0 or
			$packet->splitIndex >= $packet->splitCount or $packet->splitIndex < 0
		){
			$this->sessionManager->getLogger()->debug("Invalid split packet part from " . $this->address . ", too many parts or invalid split index (part index $packet->splitIndex, part count $packet->splitCount)");
			return null;
		}

		if(!isset($this->splitPackets[$packet->splitID])){
			if(count($this->splitPackets) >= self::MAX_SPLIT_COUNT){
				$this->sessionManager->getLogger()->debug("Ignored split packet part from " . $this->address . " because reached concurrent split packet limit of " . self::MAX_SPLIT_COUNT);
				return null;
			}
			$this->splitPackets[$packet->splitID] = array_fill(0, $packet->splitCount, null);
		}elseif(count($this->splitPackets[$packet->splitID]) !== $packet->splitCount){
			$this->sessionManager->getLogger()->debug("Wrong split count $packet->splitCount for split packet $packet->splitID from $this->address, expected " . count($this->splitPackets[$packet->splitID]));
			return null;
		}

		$this->splitPackets[$packet->splitID][$packet->splitIndex] = $packet;

		foreach($this->splitPackets[$packet->splitID] as $splitIndex => $part){
			if($part === null){
				return null;
			}
		}

		//got all parts, reassemble the packet
		$pk = new EncapsulatedPacket();
		$pk->buffer = "";

		$pk->reliability = $packet->reliability;
		$pk->messageIndex = $packet->messageIndex;
		$pk->sequenceIndex = $packet->sequenceIndex;
		$pk->orderIndex = $packet->orderIndex;
		$pk->orderChannel = $packet->orderChannel;

		for($i = 0; $i < $packet->splitCount; ++$i){
			$pk->buffer .= $this->splitPackets[$packet->splitID][$i]->buffer;
		}

		$pk->length = strlen($pk->buffer);
		unset($this->splitPackets[$packet->splitID]);

		return $pk;
	}

	private function handleEncapsulatedPacket(EncapsulatedPacket $packet) : void{
		if($packet->messageIndex !== null){
			//check for duplicates or out of range
			if($packet->messageIndex < $this->reliableWindowStart or $packet->messageIndex > $this->reliableWindowEnd or isset($this->reliableWindow[$packet->messageIndex])){
				return;
			}

			$this->reliableWindow[$packet->messageIndex] = true;

			if($packet->messageIndex === $this->reliableWindowStart){
				for(; isset($this->reliableWindow[$this->reliableWindowStart]); ++$this->reliableWindowStart){
					unset($this->reliableWindow[$this->reliableWindowStart]);
					++$this->reliableWindowEnd;
				}
			}
		}

		if($packet->hasSplit and ($packet = $this->handleSplit($packet)) === null){
			return;
		}

		if(PacketReliability::isSequencedOrOrdered($packet->reliability) and ($packet->orderChannel < 0 or $packet->orderChannel >= self::CHANNEL_COUNT)){
			//TODO: this should result in peer banning
			$this->sessionManager->getLogger()->debug("Invalid packet from " . $this->address . ", bad order channel ($packet->orderChannel)");
			return;
		}

		if(PacketReliability::isSequenced($packet->reliability)){
			if($packet->sequenceIndex < $this->receiveSequencedHighestIndex[$packet->orderChannel] or $packet->orderIndex < $this->receiveOrderedIndex[$packet->orderChannel]){
				//too old sequenced packet, discard it
				return;
			}

			$this->receiveSequencedHighestIndex[$packet->orderChannel] = $packet->sequenceIndex + 1;
			$this->handleEncapsulatedPacketRoute($packet);
		}elseif(PacketReliability::isOrdered($packet->reliability)){
			if($packet->orderIndex === $this->receiveOrderedIndex[$packet->orderChannel]){
				//this is the packet we expected to get next
				//Any ordered packet resets the sequence index to zero, so that sequenced packets older than this ordered
				//one get discarded. Sequenced packets also include (but don't increment) the order index, so a sequenced
				//packet with an order index less than this will get discarded
				$this->receiveSequencedHighestIndex[$packet->orderIndex] = 0;
				$this->receiveOrderedIndex[$packet->orderChannel] = $packet->orderIndex + 1;

				$this->handleEncapsulatedPacketRoute($packet);
				for($i = $this->receiveOrderedIndex[$packet->orderChannel]; isset($this->receiveOrderedPackets[$packet->orderChannel][$i]); ++$i){
					$this->handleEncapsulatedPacketRoute($this->receiveOrderedPackets[$packet->orderChannel][$i]);
					unset($this->receiveOrderedPackets[$packet->orderChannel][$i]);
				}

				$this->receiveOrderedIndex[$packet->orderChannel] = $i;
			}elseif($packet->orderIndex > $this->receiveOrderedIndex[$packet->orderChannel]){
				$this->receiveOrderedPackets[$packet->orderChannel][$packet->orderIndex] = $packet;
			}else{
				//duplicate/already received packet
			}
		}else{
			//not ordered or sequenced
			$this->handleEncapsulatedPacketRoute($packet);
		}
	}


	private function handleEncapsulatedPacketRoute(EncapsulatedPacket $packet) : void{
		if($this->sessionManager === null){
			return;
		}

		$id = ord($packet->buffer[0]);
		if($id < MessageIdentifiers::ID_USER_PACKET_ENUM){ //internal data packet
			if($this->state === self::STATE_CONNECTING){
				if($id === ConnectionRequest::$ID){
					$dataPacket = new ConnectionRequest($packet->buffer);
					$dataPacket->decode();

					$pk = new ConnectionRequestAccepted;
					$pk->address = $this->address;
					$pk->sendPingTime = $dataPacket->sendPingTime;
					$pk->sendPongTime = $this->sessionManager->getRakNetTimeMS();
					$this->queueConnectedPacket($pk, PacketReliability::UNRELIABLE, 0, RakLib::PRIORITY_IMMEDIATE);
				}elseif($id === NewIncomingConnection::$ID){
					$dataPacket = new NewIncomingConnection($packet->buffer);
					$dataPacket->decode();

					if($dataPacket->address->port === $this->sessionManager->getPort() or !$this->sessionManager->portChecking){
						$this->state = self::STATE_CONNECTED; //FINALLY!
						$this->isTemporal = false;
						$this->sessionManager->openSession($this);

						//$this->handlePong($dataPacket->sendPingTime, $dataPacket->sendPongTime); //can't use this due to system-address count issues in MCPE >.<
						$this->sendPing();
					}
				}
			}elseif($id === DisconnectionNotification::$ID){
				//TODO: we're supposed to send an ACK for this, but currently we're just deleting the session straight away
				$this->disconnect("client disconnect");
			}elseif($id === ConnectedPing::$ID){
				$dataPacket = new ConnectedPing($packet->buffer);
				$dataPacket->decode();

				$pk = new ConnectedPong;
				$pk->sendPingTime = $dataPacket->sendPingTime;
				$pk->sendPongTime = $this->sessionManager->getRakNetTimeMS();
				$this->queueConnectedPacket($pk, PacketReliability::UNRELIABLE, 0);
			}elseif($id === ConnectedPong::$ID){
				$dataPacket = new ConnectedPong($packet->buffer);
				$dataPacket->decode();

				$this->handlePong($dataPacket->sendPingTime, $dataPacket->sendPongTime);
			}
		}elseif($this->state === self::STATE_CONNECTED){
			$this->sessionManager->streamEncapsulated($this, $packet);
		}else{
			//$this->sessionManager->getLogger()->notice("Received packet before connection: " . bin2hex($packet->buffer));
		}
	}

	/**
	 * @param int $sendPingTime
	 * @param int $sendPongTime TODO: clock differential stuff
	 */
	private function handlePong(int $sendPingTime, int $sendPongTime) : void{
		$this->lastPingMeasure = $this->sessionManager->getRakNetTimeMS() - $sendPingTime;
		$this->sessionManager->streamPingMeasure($this, $this->lastPingMeasure);
	}

	public function handlePacket(Packet $packet) : void{
		$this->isActive = true;
		$this->lastUpdate = microtime(true);

		if($packet instanceof Datagram){ //In reality, ALL of these packets are datagrams.
			$packet->decode();

			if($packet->seqNumber < $this->windowStart or $packet->seqNumber > $this->windowEnd or isset($this->ACKQueue[$packet->seqNumber])){
				$this->sessionManager->getLogger()->debug("Received duplicate or out-of-window packet from " . $this->address . " (sequence number $packet->seqNumber, window " . $this->windowStart . "-" . $this->windowEnd . ")");
				return;
			}

			unset($this->NACKQueue[$packet->seqNumber]);
			$this->ACKQueue[$packet->seqNumber] = $packet->seqNumber;
			if($this->highestSeqNumberThisTick < $packet->seqNumber){
				$this->highestSeqNumberThisTick = $packet->seqNumber;
			}

			if($packet->seqNumber === $this->windowStart){
				//got a contiguous packet, shift the receive window
				//this packet might complete a sequence of out-of-order packets, so we incrementally check the indexes
				//to see how far to shift the window, and stop as soon as we either find a gap or have an empty window
				for(; isset($this->ACKQueue[$this->windowStart]); ++$this->windowStart){
					++$this->windowEnd;
				}
			}elseif($packet->seqNumber > $this->windowStart){
				//we got a gap - a later packet arrived before earlier ones did
				//we add the earlier ones to the NACK queue
				//if the missing packets arrive before the end of tick, they'll be removed from the NACK queue
				for($i = $this->windowStart; $i < $packet->seqNumber; ++$i){
					if(!isset($this->ACKQueue[$i])){
						$this->NACKQueue[$i] = $i;
					}
				}
			}else{
				assert(false, "received packet before window start");
			}

			foreach($packet->packets as $pk){
				$this->handleEncapsulatedPacket($pk);
			}
		}else{
			if($packet instanceof ACK){
				$packet->decode();
				foreach($packet->packets as $seq){
					if(isset($this->recoveryQueue[$seq])){
						foreach($this->recoveryQueue[$seq]->packets as $pk){
							if($pk instanceof EncapsulatedPacket and $pk->needACK and $pk->messageIndex !== null){
								unset($this->needACK[$pk->identifierACK][$pk->messageIndex]);
							}
						}
						unset($this->recoveryQueue[$seq]);
					}
				}
			}elseif($packet instanceof NACK){
				$packet->decode();
				foreach($packet->packets as $seq){
					if(isset($this->recoveryQueue[$seq])){
						$this->packetToSend[] = $this->recoveryQueue[$seq];
						unset($this->recoveryQueue[$seq]);
					}
				}
			}
		}
	}

	public function flagForDisconnection() : void{
		$this->state = self::STATE_DISCONNECTING;
		$this->disconnectionTime = microtime(true);
	}

	public function close() : void{
		if($this->state !== self::STATE_DISCONNECTED){
			$this->state = self::STATE_DISCONNECTED;

			//TODO: the client will send an ACK for this, but we aren't handling it (debug spam)
			$this->queueConnectedPacket(new DisconnectionNotification(), PacketReliability::RELIABLE_ORDERED, 0, RakLib::PRIORITY_IMMEDIATE);

			$this->sessionManager->getLogger()->debug("Closed session for $this->address");
			$this->sessionManager->removeSessionInternal($this);
		}
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

use function strlen;
use function substr;

class Datagram extends Packet{
	public const BITFLAG_VALID = 0x80;
	public const BITFLAG_ACK = 0x40;
	public const BITFLAG_NAK = 0x20; // hasBAndAS for ACKs

	/*
	 * These flags can be set on regular datagrams, but they are useless as per the public version of RakNet
	 * (the receiving client will not use them or pay any attention to them).
	 */
	public const BITFLAG_PACKET_PAIR = 0x10;
	public const BITFLAG_CONTINUOUS_SEND = 0x08;
	public const BITFLAG_NEEDS_B_AND_AS = 0x04;

	/** @var int */
	public $headerFlags = 0;

	/** @var (EncapsulatedPacket|string)[] */
	public $packets = [];

	/** @var int|null */
	public $seqNumber = null;

	protected function encodeHeader() : void{
		($this->buffer .= \chr(self::BITFLAG_VALID | $this->headerFlags));
	}

	protected function encodePayload() : void{
		($this->buffer .= (\substr(\pack("V", $this->seqNumber), 0, -1)));
		foreach($this->packets as $packet){
			($this->buffer .= $packet instanceof EncapsulatedPacket ? $packet->toBinary() : (string) $packet);
		}
	}

	public function length(){
		$length = 4;
		foreach($this->packets as $packet){
			$length += $packet instanceof EncapsulatedPacket ? $packet->getTotalLength() : strlen($packet);
		}

		return $length;
	}

	protected function decodeHeader() : void{
		$this->headerFlags = (\ord($this->get(1)));
	}

	protected function decodePayload() : void{
		$this->seqNumber = ((\unpack("V", $this->get(3) . "\x00")[1]));

		while(!$this->feof()){
			$offset = 0;
			$data = substr($this->buffer, $this->offset);
			$packet = EncapsulatedPacket::fromBinary($data, $offset);
			$this->offset += $offset;
			if($packet->buffer === ''){
				break;
			}
			$this->packets[] = $packet;
		}
	}

	public function clean(){
		$this->packets = [];
		$this->seqNumber = null;

		return parent::clean();
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

abstract class PacketReliability{

	/*
	 * From https://github.com/OculusVR/RakNet/blob/master/Source/PacketPriority.h
	 *
	 * Default: 0b010 (2) or 0b011 (3)
	 */

	public const UNRELIABLE = 0;
	public const UNRELIABLE_SEQUENCED = 1;
	public const RELIABLE = 2;
	public const RELIABLE_ORDERED = 3;
	public const RELIABLE_SEQUENCED = 4;
	public const UNRELIABLE_WITH_ACK_RECEIPT = 5;
	public const RELIABLE_WITH_ACK_RECEIPT = 6;
	public const RELIABLE_ORDERED_WITH_ACK_RECEIPT = 7;

	public static function isReliable(int $reliability) : bool{
		return (
			$reliability === self::RELIABLE or
			$reliability === self::RELIABLE_ORDERED or
			$reliability === self::RELIABLE_SEQUENCED or
			$reliability === self::RELIABLE_WITH_ACK_RECEIPT or
			$reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT
		);
	}

	public static function isSequenced(int $reliability) : bool{
		return (
			$reliability === self::UNRELIABLE_SEQUENCED or
			$reliability === self::RELIABLE_SEQUENCED
		);
	}

	public static function isOrdered(int $reliability) : bool{
		return (
			$reliability === self::RELIABLE_ORDERED or
			$reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT
		);
	}

	public static function isSequencedOrOrdered(int $reliability) : bool{
		return (
			$reliability === self::UNRELIABLE_SEQUENCED or
			$reliability === self::RELIABLE_ORDERED or
			$reliability === self::RELIABLE_SEQUENCED or
			$reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT
		);
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class ConnectedPing extends Packet{
	public static $ID = MessageIdentifiers::ID_CONNECTED_PING;

	/** @var int */
	public $sendPingTime;

	protected function encodePayload() : void{
		($this->buffer .= (\pack("NN", $this->sendPingTime >> 32, $this->sendPingTime & 0xFFFFFFFF)));
	}

	protected function decodePayload() : void{
		$this->sendPingTime = (Binary::readLong($this->get(8)));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use function ceil;
use function chr;
use function ord;
use function strlen;
use function substr;

use pocketmine\utils\Binary;

class EncapsulatedPacket{
	private const RELIABILITY_SHIFT = 5;
	private const RELIABILITY_FLAGS = 0b111 << self::RELIABILITY_SHIFT;

	private const SPLIT_FLAG = 0b00010000;

	/** @var int */
	public $reliability;
	/** @var bool */
	public $hasSplit = false;
	/** @var int */
	public $length = 0;
	/** @var int|null */
	public $messageIndex;
	/** @var int|null */
	public $sequenceIndex;
	/** @var int|null */
	public $orderIndex;
	/** @var int|null */
	public $orderChannel;
	/** @var int|null */
	public $splitCount;
	/** @var int|null */
	public $splitID;
	/** @var int|null */
	public $splitIndex;
	/** @var string */
	public $buffer = "";
	/** @var bool */
	public $needACK = false;
	/** @var int|null */
	public $identifierACK;

	/**
	 * Decodes an EncapsulatedPacket from bytes generated by toInternalBinary().
	 *
	 * @param string   $bytes
	 * @param int|null $offset reference parameter, will be set to the number of bytes read
	 *
	 * @return EncapsulatedPacket
	 */
	public static function fromInternalBinary(string $bytes, ?int &$offset = null) : EncapsulatedPacket{
		$packet = new EncapsulatedPacket();

		$offset = 0;
		$packet->reliability = ord($bytes[$offset++]);

		$length = (\unpack("N", substr($bytes, $offset, 4))[1] << 32 >> 32);
		$offset += 4;
		$packet->identifierACK = (\unpack("N", substr($bytes, $offset, 4))[1] << 32 >> 32); //TODO: don't read this for non-ack-receipt reliabilities
		$offset += 4;

		if(PacketReliability::isSequencedOrOrdered($packet->reliability)){
			$packet->orderChannel = ord($bytes[$offset++]);
		}

		$packet->buffer = substr($bytes, $offset, $length);
		$offset += $length;
		return $packet;
	}

	/**
	 * Encodes data needed for the EncapsulatedPacket to be transmitted from RakLib to the implementation's thread.
	 * @return string
	 */
	public function toInternalBinary() : string{
		return
			chr($this->reliability) .
			(\pack("N", strlen($this->buffer))) .
			(\pack("N", $this->identifierACK ?? -1)) . //TODO: don't write this for non-ack-receipt reliabilities
			(PacketReliability::isSequencedOrOrdered($this->reliability) ? chr($this->orderChannel) : "") .
			$this->buffer;
	}

	/**
	 * @param string $binary
	 * @param int    $offset reference parameter
	 *
	 * @return EncapsulatedPacket
	 */
	public static function fromBinary(string $binary, ?int &$offset = null) : EncapsulatedPacket{

		$packet = new EncapsulatedPacket();

		$flags = ord($binary[0]);
		$packet->reliability = $reliability = ($flags & self::RELIABILITY_FLAGS) >> self::RELIABILITY_SHIFT;
		$packet->hasSplit = $hasSplit = ($flags & self::SPLIT_FLAG) > 0;

		$length = (int) ceil((\unpack("n", substr($binary, 1, 2))[1]) / 8);
		$offset = 3;

		if(PacketReliability::isReliable($reliability)){
			$packet->messageIndex = (\unpack("V", substr($binary, $offset, 3) . "\x00")[1]);
			$offset += 3;
		}

		if(PacketReliability::isSequenced($reliability)){
			$packet->sequenceIndex = (\unpack("V", substr($binary, $offset, 3) . "\x00")[1]);
			$offset += 3;
		}

		if(PacketReliability::isSequencedOrOrdered($reliability)){
			$packet->orderIndex = (\unpack("V", substr($binary, $offset, 3) . "\x00")[1]);
			$offset += 3;
			$packet->orderChannel = ord($binary[$offset++]);
		}

		if($hasSplit){
			$packet->splitCount = (\unpack("N", substr($binary, $offset, 4))[1] << 32 >> 32);
			$offset += 4;
			$packet->splitID = (\unpack("n", substr($binary, $offset, 2))[1]);
			$offset += 2;
			$packet->splitIndex = (\unpack("N", substr($binary, $offset, 4))[1] << 32 >> 32);
			$offset += 4;
		}

		$packet->buffer = substr($binary, $offset, $length);
		$offset += $length;

		return $packet;
	}

	/**
	 * @return string
	 */
	public function toBinary() : string{
		return
			chr(($this->reliability << self::RELIABILITY_SHIFT) | ($this->hasSplit ? self::SPLIT_FLAG : 0)) .
			(\pack("n", strlen($this->buffer) << 3)) .
			(PacketReliability::isReliable($this->reliability) ? (\substr(\pack("V", $this->messageIndex), 0, -1)) : "") .
			(PacketReliability::isSequenced($this->reliability) ? (\substr(\pack("V", $this->sequenceIndex), 0, -1)) : "") .
			(PacketReliability::isSequencedOrOrdered($this->reliability) ? (\substr(\pack("V", $this->orderIndex), 0, -1)) . chr($this->orderChannel) : "") .
			($this->hasSplit ? (\pack("N", $this->splitCount)) . (\pack("n", $this->splitID)) . (\pack("N", $this->splitIndex)) : "")
			. $this->buffer;
	}

	public function getTotalLength() : int{
		return
			1 + //reliability
			2 + //length
			(PacketReliability::isReliable($this->reliability) ? 3 : 0) + //message index
			(PacketReliability::isSequenced($this->reliability) ? 3 : 0) + //sequence index
			(PacketReliability::isSequencedOrOrdered($this->reliability) ? 3 + 1 : 0) + //order index (3) + order channel (1)
			($this->hasSplit ? 4 + 2 + 4 : 0) + //split count (4) + split ID (2) + split index (4)
			strlen($this->buffer);
	}

	public function __toString() : string{
		return $this->toBinary();
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

class ACK extends AcknowledgePacket{
	public static $ID = 0xc0;
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;


use function chr;
use function count;
use function sort;
use const SORT_NUMERIC;

use pocketmine\utils\Binary;

abstract class AcknowledgePacket extends Packet{
	private const RECORD_TYPE_RANGE = 0;
	private const RECORD_TYPE_SINGLE = 1;

	/** @var int[] */
	public $packets = [];

	protected function encodePayload() : void{
		$payload = "";
		sort($this->packets, SORT_NUMERIC);
		$count = count($this->packets);
		$records = 0;

		if($count > 0){
			$pointer = 1;
			$start = $this->packets[0];
			$last = $this->packets[0];

			while($pointer < $count){
				$current = $this->packets[$pointer++];
				$diff = $current - $last;
				if($diff === 1){
					$last = $current;
				}elseif($diff > 1){ //Forget about duplicated packets (bad queues?)
					if($start === $last){
						$payload .= chr(self::RECORD_TYPE_SINGLE);
						$payload .= (\substr(\pack("V", $start), 0, -1));
						$start = $last = $current;
					}else{
						$payload .= chr(self::RECORD_TYPE_RANGE);
						$payload .= (\substr(\pack("V", $start), 0, -1));
						$payload .= (\substr(\pack("V", $last), 0, -1));
						$start = $last = $current;
					}
					++$records;
				}
			}

			if($start === $last){
				$payload .= chr(self::RECORD_TYPE_SINGLE);
				$payload .= (\substr(\pack("V", $start), 0, -1));
			}else{
				$payload .= chr(self::RECORD_TYPE_RANGE);
				$payload .= (\substr(\pack("V", $start), 0, -1));
				$payload .= (\substr(\pack("V", $last), 0, -1));
			}
			++$records;
		}

		($this->buffer .= (\pack("n", $records)));
		$this->buffer .= $payload;
	}

	protected function decodePayload() : void{
		$count = ((\unpack("n", $this->get(2))[1]));
		$this->packets = [];
		$cnt = 0;
		for($i = 0; $i < $count and !$this->feof() and $cnt < 4096; ++$i){
			if((\ord($this->get(1))) === self::RECORD_TYPE_RANGE){
				$start = ((\unpack("V", $this->get(3) . "\x00")[1]));
				$end = ((\unpack("V", $this->get(3) . "\x00")[1]));
				if(($end - $start) > 512){
					$end = $start + 512;
				}
				for($c = $start; $c <= $end; ++$c){
					$this->packets[$cnt++] = $c;
				}
			}else{
				$this->packets[$cnt++] = ((\unpack("V", $this->get(3) . "\x00")[1]));
			}
		}
	}

	public function clean(){
		$this->packets = [];

		return parent::clean();
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class ConnectionRequest extends Packet{
	public static $ID = MessageIdentifiers::ID_CONNECTION_REQUEST;

	/** @var int */
	public $clientID;
	/** @var int */
	public $sendPingTime;
	/** @var bool */
	public $useSecurity = false;

	protected function encodePayload() : void{
		($this->buffer .= (\pack("NN", $this->clientID >> 32, $this->clientID & 0xFFFFFFFF)));
		($this->buffer .= (\pack("NN", $this->sendPingTime >> 32, $this->sendPingTime & 0xFFFFFFFF)));
		($this->buffer .= \chr($this->useSecurity ? 1 : 0));
	}

	protected function decodePayload() : void{
		$this->clientID = (Binary::readLong($this->get(8)));
		$this->sendPingTime = (Binary::readLong($this->get(8)));
		$this->useSecurity = (\ord($this->get(1))) !== 0;
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

use raklib\RakLib;
use raklib\utils\InternetAddress;
use function strlen;

class ConnectionRequestAccepted extends Packet{
	public static $ID = MessageIdentifiers::ID_CONNECTION_REQUEST_ACCEPTED;

	/** @var InternetAddress */
	public $address;
	/** @var InternetAddress[] */
	public $systemAddresses = [];

	/** @var int */
	public $sendPingTime;
	/** @var int */
	public $sendPongTime;

	public function __construct(string $buffer = "", int $offset = 0){
		parent::__construct($buffer, $offset);
		$this->systemAddresses[] = new InternetAddress("127.0.0.1", 0, 4);
	}

	protected function encodePayload() : void{
		$this->putAddress($this->address);
		($this->buffer .= (\pack("n", 0)));

		$dummy = new InternetAddress("0.0.0.0", 0, 4);
		for($i = 0; $i < RakLib::$SYSTEM_ADDRESS_COUNT; ++$i){
			$this->putAddress($this->systemAddresses[$i] ?? $dummy);
		}

		($this->buffer .= (\pack("NN", $this->sendPingTime >> 32, $this->sendPingTime & 0xFFFFFFFF)));
		($this->buffer .= (\pack("NN", $this->sendPongTime >> 32, $this->sendPongTime & 0xFFFFFFFF)));
	}

	protected function decodePayload() : void{
		$this->address = $this->getAddress();
		((\unpack("n", $this->get(2))[1])); //TODO: check this

		$len = strlen($this->buffer);
		$dummy = new InternetAddress("0.0.0.0", 0, 4);

		for($i = 0; $i < RakLib::$SYSTEM_ADDRESS_COUNT; ++$i){
			$this->systemAddresses[$i] = $this->offset + 16 < $len ? $this->getAddress() : $dummy; //HACK: avoids trying to read too many addresses on bad data
		}

		$this->sendPingTime = (Binary::readLong($this->get(8)));
		$this->sendPongTime = (Binary::readLong($this->get(8)));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

use raklib\RakLib;
use raklib\utils\InternetAddress;
use function strlen;

class NewIncomingConnection extends Packet{
	public static $ID = MessageIdentifiers::ID_NEW_INCOMING_CONNECTION;

	/** @var InternetAddress */
	public $address;

	/** @var InternetAddress[] */
	public $systemAddresses = [];

	/** @var int */
	public $sendPingTime;
	/** @var int */
	public $sendPongTime;

	protected function encodePayload() : void{
		$this->putAddress($this->address);
		foreach($this->systemAddresses as $address){
			$this->putAddress($address);
		}
		($this->buffer .= (\pack("NN", $this->sendPingTime >> 32, $this->sendPingTime & 0xFFFFFFFF)));
		($this->buffer .= (\pack("NN", $this->sendPongTime >> 32, $this->sendPongTime & 0xFFFFFFFF)));
	}

	protected function decodePayload() : void{
		$this->address = $this->getAddress();

		//TODO: HACK!
		$stopOffset = strlen($this->buffer) - 16; //buffer length - sizeof(sendPingTime) - sizeof(sendPongTime)
		$dummy = new InternetAddress("0.0.0.0", 0, 4);
		for($i = 0; $i < RakLib::$SYSTEM_ADDRESS_COUNT; ++$i){
			if($this->offset >= $stopOffset){
				$this->systemAddresses[$i] = clone $dummy;
			}else{
				$this->systemAddresses[$i] = $this->getAddress();
			}
		}

		$this->sendPingTime = (Binary::readLong($this->get(8)));
		$this->sendPongTime = (Binary::readLong($this->get(8)));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

class DisconnectionNotification extends Packet{
	public static $ID = MessageIdentifiers::ID_DISCONNECTION_NOTIFICATION;

	protected function encodePayload() : void{

	}

	protected function decodePayload() : void{

	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;

use pocketmine\utils\Binary;

class ConnectedPong extends Packet{
	public static $ID = MessageIdentifiers::ID_CONNECTED_PONG;

	/** @var int */
	public $sendPingTime;
	/** @var int */
	public $sendPongTime;

	protected function encodePayload() : void{
		($this->buffer .= (\pack("NN", $this->sendPingTime >> 32, $this->sendPingTime & 0xFFFFFFFF)));
		($this->buffer .= (\pack("NN", $this->sendPongTime >> 32, $this->sendPongTime & 0xFFFFFFFF)));
	}

	protected function decodePayload() : void{
		$this->sendPingTime = (Binary::readLong($this->get(8)));
		$this->sendPongTime = (Binary::readLong($this->get(8)));
	}
}
<?php

/*
 * RakLib network library
 *
 *
 * This project is not affiliated with Jenkins Software LLC nor RakNet.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 */

declare(strict_types=1);

namespace raklib\protocol;


class NACK extends AcknowledgePacket{
	public static $ID = 0xa0;
}
