diff --git a/src/build/jenkins.sh b/src/build/jenkins.sh index 2ed6ef764..e1f16d94a 100644 --- a/src/build/jenkins.sh +++ b/src/build/jenkins.sh @@ -32,7 +32,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/linux/32bit cd $COMPILEDIR/linux/32bit - $SCRIPT -t linux32 -o -j 2 -c -f x86 + $SCRIPT -t linux32 -o -j 2 -c -z -f x86 tar -czf PHP_${PHP_VERSION}_x86_Linux.tar.gz bin/ cp -r $COMPILEDIR/linux/32bit/{install.log,PHP_${PHP_VERSION}_x86_Linux.tar.gz} $ARCHIVE/linux/32bit/ @@ -46,7 +46,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/linux/64bit cd $COMPILEDIR/linux/64bit - $SCRIPT -t linux64 -o -j 2 -c -f x86_64 + $SCRIPT -t linux64 -o -j 2 -c -z -f x86_64 tar -czf PHP_${PHP_VERSION}_x86-64_Linux.tar.gz bin/ cp -r $COMPILEDIR/linux/64bit/{install.log,PHP_${PHP_VERSION}_x86-64_Linux.tar.gz} $ARCHIVE/linux/64bit/ @@ -69,7 +69,7 @@ then rm -rf libtool-2.4.2 export LIBTOOL="$COMPILEDIR/mac/libtool/bin/libtool" export LIBTOOLIZE="$COMPILEDIR/mac/libtool/bin/libtoolize" - $SCRIPT -t mac32 -o -j 1 -c -f + $SCRIPT -t mac32 -o -j 1 -c -z -f tar -czf PHP_${PHP_VERSION}_x86_MacOS.tar.gz bin/ cp -r $COMPILEDIR/mac32/{install.log,PHP_${PHP_VERSION}_x86_MacOS.tar.gz} $ARCHIVE/mac32/ @@ -92,7 +92,7 @@ then rm -rf libtool-2.4.2 export LIBTOOL="$COMPILEDIR/mac/libtool/bin/libtool" export LIBTOOLIZE="$COMPILEDIR/mac/libtool/bin/libtoolize" - $SCRIPT -t mac64 -o -j 1 -c -f + $SCRIPT -t mac64 -o -j 1 -c -z -f tar -czf PHP_${PHP_VERSION}_x86-64_MacOS.tar.gz bin/ cp -r $COMPILEDIR/mac64/{install.log,PHP_${PHP_VERSION}_x86-64_MacOS.tar.gz} $ARCHIVE/mac64 @@ -106,7 +106,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/rpi cd $COMPILEDIR/rpi - $SCRIPT -t rpi -o -j 1 -c -f arm + $SCRIPT -t rpi -o -j 1 -c -z -f arm tar -czf PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz bin/ cp -r $COMPILEDIR/rpi/{install.log,PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz} $ARCHIVE/rpi/ @@ -120,7 +120,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/android-armv6 cd $COMPILEDIR/crosscompile/android-armv6 - $SCRIPT -t android-armv6 -o -j 1 -c -x -s -f arm + $SCRIPT -t android-armv6 -o -j 1 -c -x -s -z -f arm tar -czf PHP_${PHP_VERSION}_ARMv6_Android.tar.gz bin/ cp -r $COMPILEDIR/crosscompile/android-armv6/{install.log,PHP_${PHP_VERSION}_ARMv6_Android.tar.gz} $ARCHIVE/crosscompile/android-armv6/ @@ -134,7 +134,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/android-armv7 cd $COMPILEDIR/crosscompile/android-armv7 - $SCRIPT -t android-armv7 -o -j 1 -c -x -s -f arm + $SCRIPT -t android-armv7 -o -j 1 -c -x -s -z -f arm tar -czf PHP_${PHP_VERSION}_ARMv7_Android.tar.gz bin/ cp -r $COMPILEDIR/crosscompile/android-armv7/{install.log,PHP_${PHP_VERSION}_ARMv7_Android.tar.gz} $ARCHIVE/crosscompile/android-armv7/ @@ -156,7 +156,7 @@ then rm -rf libtool-2.4.2 export LIBTOOL="$COMPILEDIR/crosscompile/ios-armv6/libtool/bin/libtool" export LIBTOOLIZE="$COMPILEDIR/crosscompile/ios-armv6/libtool/bin/libtoolize" - PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x + PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x -z -f arm cp -r $COMPILEDIR/crosscompile/ios-armv6/{install.log,bin/*} $ARCHIVE/crosscompile/ios-armv6/ if [ ! -f $COMPILEDIR/crosscompile/ios-armv6/bin/php5/bin/php ]; then @@ -177,7 +177,7 @@ then rm -rf libtool-2.4.2 export LIBTOOL="$COMPILEDIR/crosscompile/ios-armv7/libtool/bin/libtool" export LIBTOOLIZE="$COMPILEDIR/crosscompile/ios-armv7/libtool/bin/libtoolize" - PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x + PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x -z -f arm cp -r $COMPILEDIR/crosscompile/ios-armv7/{install.log,bin/*} $ARCHIVE/crosscompile/ios-armv7/ if [ ! -f $COMPILEDIR/crosscompile/ios-armv7/bin/php5/bin/php ]; then @@ -190,7 +190,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/rpi cd $COMPILEDIR/crosscompile/rpi - $SCRIPT -t rpi -o -j 1 -c -x -f arm + $SCRIPT -t rpi -o -j 1 -c -x -z -f arm tar -czf PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz bin/ cp -r $COMPILEDIR/crosscompile/rpi/{install.log,PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz} $ARCHIVE/crosscompile/rpi/ @@ -204,7 +204,7 @@ then mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/mac cd $COMPILEDIR/crosscompile/mac - $SCRIPT -t mac -o -j 1 -c -f -x + $SCRIPT -t mac -o -j 1 -c -f -z -x cp -r $COMPILEDIR/crosscompile/mac/{install.log,bin/*} $ARCHIVE/crosscompile/mac/ if [ ! -f $COMPILEDIR/crosscompile/mac/bin/php5/bin/php ]; then diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index dced61e6e..3d6e3d766 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -76,6 +76,7 @@ use pocketmine\tile\Furnace; use pocketmine\tile\Sign; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; +use pocketmine\utils\Binary; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -1250,7 +1251,7 @@ class Player extends Human implements CommandSender, IPlayer{ $pk = new ServerHandshakePacket; $pk->port = $this->port; $pk->session = $packet->session; - $pk->session2 = Utils::readLong("\x00\x00\x00\x00\x04\x44\x0b\xa9"); + $pk->session2 = Binary::readLong("\x00\x00\x00\x00\x04\x44\x0b\xa9"); $this->dataPacket($pk); break; case ProtocolInfo::CLIENT_HANDSHAKE_PACKET: diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 6c06eb7c3..1ac03c500 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -77,6 +77,7 @@ namespace { } namespace pocketmine { + use pocketmine\utils\Binary; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\wizard\Installer; @@ -358,6 +359,7 @@ namespace pocketmine { define("pocketmine\\GIT_COMMIT", str_repeat("00", 20)); } + @define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN)); @ini_set("opcache.mmap_base", bin2hex(Utils::getRandomBytes(8, false))); //Fix OPCache address errors if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index fc05e03a9..588d24b4f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -77,6 +77,7 @@ use pocketmine\scheduler\ServerScheduler; use pocketmine\scheduler\TickScheduler; use pocketmine\tile\Sign; use pocketmine\tile\Tile; +use pocketmine\utils\Binary; use pocketmine\utils\Config; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -899,7 +900,7 @@ class Server{ $generator = new Normal($options); } } - $gen = new WorldGenerator($this, $generator, $name, $seed === null ? Utils::readInt(Utils::getRandomBytes(4, false)) : (int) $seed); + $gen = new WorldGenerator($this, $generator, $name, $seed === null ? Binary::readInt(Utils::getRandomBytes(4, false)) : (int) $seed); $gen->generate(); $gen->close(); @@ -1219,7 +1220,7 @@ class Server{ console("[INFO] Starting Minecraft PE server on " . ($this->getIp() === "" ? "*" : $this->getIp()) . ":" . $this->getPort()); define("BOOTUP_RANDOM", Utils::getRandomBytes(16)); - $this->serverID = Utils::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 0, 8)); + $this->serverID = Binary::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 0, 8)); $this->interface = new ThreadedHandler("255.255.255.255", $this->getPort(), $this->getIp() === "" ? "0.0.0.0" : $this->getIp()); console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0); @@ -1789,7 +1790,7 @@ class Server{ } $this->lastSendUsage = new SendUsageTask("http://stats.pocketmine.net/usage.php", array( - "serverid" => Utils::readLong(substr(Utils::getUniqueID(true, $this->getIp() .":". $this->getPort()), 0, 8)), + "serverid" => Binary::readLong(substr(Utils::getUniqueID(true, $this->getIp() .":". $this->getPort()), 0, 8)), "port" => $this->getPort(), "os" => Utils::getOS(), "memory_total" => $this->getConfigString("memory-limit"), diff --git a/src/pocketmine/level/LevelImport.php b/src/pocketmine/level/LevelImport.php index 73d24e0ae..fa6f44b45 100644 --- a/src/pocketmine/level/LevelImport.php +++ b/src/pocketmine/level/LevelImport.php @@ -21,6 +21,7 @@ namespace pocketmine\level; +use pocketmine\level\format\PocketChunkParser; use pocketmine\nbt\NBT; use pocketmine\pmf\LevelFormat; use pocketmine\utils\Config; diff --git a/src/pocketmine/level/WorldGenerator.php b/src/pocketmine/level/WorldGenerator.php index 7bfcdeda6..651bc20a4 100644 --- a/src/pocketmine/level/WorldGenerator.php +++ b/src/pocketmine/level/WorldGenerator.php @@ -24,6 +24,7 @@ namespace pocketmine\level; use pocketmine\level\generator\Generator; use pocketmine\pmf\LevelFormat; use pocketmine\Server; +use pocketmine\utils\Binary; use pocketmine\utils\Random; use pocketmine\utils\Utils; @@ -37,7 +38,7 @@ class WorldGenerator{ * @param int $seed */ public function __construct(Server $server, Generator $generator, $name, $seed = null){ - $this->seed = $seed !== null ? (int) $seed : Utils::readInt(Utils::getRandomBytes(4, false)); + $this->seed = $seed !== null ? (int) $seed : Binary::readInt(Utils::getRandomBytes(4, false)); $this->random = new Random($this->seed); $this->server = $server; $this->path = $this->server->getDataPath() . "worlds/" . $name . "/"; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php new file mode 100644 index 000000000..869fdf9b4 --- /dev/null +++ b/src/pocketmine/level/format/Chunk.php @@ -0,0 +1,90 @@ +location = array(); console("[DEBUG] Loading Chunk Location table...", true, true, 2); for($offset = 0; $offset < 0x1000; $offset += 4){ - $data = Utils::readLInt(substr($this->raw, $offset, 4)); + $data = Binary::readLInt(substr($this->raw, $offset, 4)); $sectors = $data & 0xff; if($sectors === 0){ continue; @@ -105,14 +106,14 @@ class PocketChunkParser{ } } - return Utils::writeLInt(strlen($chunk)) . $chunk; + return Binary::writeLInt(strlen($chunk)) . $chunk; } public function parseChunk($X, $Z){ $X = (int) $X; $Z = (int) $Z; $offset = $this->getOffset($X, $Z); - $len = Utils::readLInt(substr($this->raw, $offset, 4)); + $len = Binary::readLInt(substr($this->raw, $offset, 4)); $offset += 4; $chunk = array( 0 => array(), //Block diff --git a/src/pocketmine/level/format/anvil/Anvil.php b/src/pocketmine/level/format/anvil/Anvil.php new file mode 100644 index 000000000..2c2282efa --- /dev/null +++ b/src/pocketmine/level/format/anvil/Anvil.php @@ -0,0 +1,36 @@ +basePath = realpath($path) . "/"; + } + + public static function isValid($path){ + return file_exists(realpath($path) . "region/"); + } +} \ No newline at end of file diff --git a/src/pocketmine/nbt/NBT.php b/src/pocketmine/nbt/NBT.php index d29f93fbc..90b7f7032 100644 --- a/src/pocketmine/nbt/NBT.php +++ b/src/pocketmine/nbt/NBT.php @@ -38,6 +38,7 @@ use pocketmine\nbt\tag\NamedTAG; use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\Tag; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; /** @@ -188,51 +189,51 @@ class NBT{ } public function getByte($signed = false){ - return Utils::readByte($this->get(1), $signed); + return Binary::readByte($this->get(1), $signed); } public function putByte($v){ - $this->buffer .= Utils::writeByte($v); + $this->buffer .= Binary::writeByte($v); } public function getShort(){ - return $this->endianness === self::BIG_ENDIAN ? Utils::readShort($this->get(2)) : Utils::readLShort($this->get(2)); + return $this->endianness === self::BIG_ENDIAN ? Binary::readShort($this->get(2)) : Binary::readLShort($this->get(2)); } public function putShort($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Utils::writeShort($v) : Utils::writeLShort($v); + $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeShort($v) : Binary::writeLShort($v); } public function getInt(){ - return $this->endianness === self::BIG_ENDIAN ? Utils::readInt($this->get(4)) : Utils::readLInt($this->get(4)); + return $this->endianness === self::BIG_ENDIAN ? Binary::readInt($this->get(4)) : Binary::readLInt($this->get(4)); } public function putInt($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Utils::writeInt($v) : Utils::writeLInt($v); + $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeInt($v) : Binary::writeLInt($v); } public function getLong(){ - return $this->endianness === self::BIG_ENDIAN ? Utils::readLong($this->get(8)) : Utils::readLLong($this->get(8)); + return $this->endianness === self::BIG_ENDIAN ? Binary::readLong($this->get(8)) : Binary::readLLong($this->get(8)); } public function putLong($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Utils::writeLong($v) : Utils::writeLLong($v); + $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeLong($v) : Binary::writeLLong($v); } public function getFloat(){ - return $this->endianness === self::BIG_ENDIAN ? Utils::readFloat($this->get(4)) : Utils::readLFloat($this->get(4)); + return $this->endianness === self::BIG_ENDIAN ? Binary::readFloat($this->get(4)) : Binary::readLFloat($this->get(4)); } public function putFloat($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Utils::writeFloat($v) : Utils::writeLFloat($v); + $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeFloat($v) : Binary::writeLFloat($v); } public function getDouble(){ - return $this->endianness === self::BIG_ENDIAN ? Utils::readDouble($this->get(8)) : Utils::readLDouble($this->get(8)); + return $this->endianness === self::BIG_ENDIAN ? Binary::readDouble($this->get(8)) : Binary::readLDouble($this->get(8)); } public function putDouble($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Utils::writeDouble($v) : Utils::writeLDouble($v); + $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeDouble($v) : Binary::writeLDouble($v); } public function getString(){ diff --git a/src/pocketmine/network/protocol/AddMobPacket.php b/src/pocketmine/network/protocol/AddMobPacket.php index 31d95812e..6babe301e 100644 --- a/src/pocketmine/network/protocol/AddMobPacket.php +++ b/src/pocketmine/network/protocol/AddMobPacket.php @@ -21,6 +21,7 @@ namespace pocketmine\network\protocol; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class AddMobPacket extends DataPacket{ @@ -50,7 +51,7 @@ class AddMobPacket extends DataPacket{ $this->putFloat($this->z); $this->putByte($this->yaw); $this->putByte($this->pitch); - $this->put(Utils::writeMetadata($this->metadata)); + $this->put(Binary::writeMetadata($this->metadata)); } } \ No newline at end of file diff --git a/src/pocketmine/network/protocol/AddPlayerPacket.php b/src/pocketmine/network/protocol/AddPlayerPacket.php index 4e32892e6..e6b4c5fac 100644 --- a/src/pocketmine/network/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/protocol/AddPlayerPacket.php @@ -21,6 +21,7 @@ namespace pocketmine\network\protocol; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class AddPlayerPacket extends DataPacket{ @@ -56,7 +57,7 @@ class AddPlayerPacket extends DataPacket{ $this->putByte($this->pitch); $this->putShort($this->unknown1); $this->putShort($this->unknown2); - $this->put(Utils::writeMetadata($this->metadata)); + $this->put(Binary::writeMetadata($this->metadata)); } } \ No newline at end of file diff --git a/src/pocketmine/network/protocol/DataPacket.php b/src/pocketmine/network/protocol/DataPacket.php index 798751ce8..ac820ca04 100644 --- a/src/pocketmine/network/protocol/DataPacket.php +++ b/src/pocketmine/network/protocol/DataPacket.php @@ -22,6 +22,7 @@ namespace pocketmine\network\protocol; use pocketmine\item\Item; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; abstract class DataPacket extends \stdClass{ @@ -79,52 +80,52 @@ abstract class DataPacket extends \stdClass{ } protected function getLong($unsigned = false){ - return Utils::readLong($this->get(8), $unsigned); + return Binary::readLong($this->get(8), $unsigned); } protected function putLong($v){ - $this->buffer .= Utils::writeLong($v); + $this->buffer .= Binary::writeLong($v); } protected function getInt(){ - return Utils::readInt($this->get(4)); + return Binary::readInt($this->get(4)); } protected function putInt($v){ - $this->buffer .= Utils::writeInt($v); + $this->buffer .= Binary::writeInt($v); } protected function getShort($unsigned = false){ - return Utils::readShort($this->get(2), $unsigned); + return Binary::readShort($this->get(2), $unsigned); } protected function putShort($v){ - $this->buffer .= Utils::writeShort($v); + $this->buffer .= Binary::writeShort($v); } protected function getFloat(){ - return Utils::readFloat($this->get(4)); + return Binary::readFloat($this->get(4)); } protected function putFloat($v){ - $this->buffer .= Utils::writeFloat($v); + $this->buffer .= Binary::writeFloat($v); } protected function getTriad(){ - return Utils::readTriad($this->get(3)); + return Binary::readTriad($this->get(3)); } protected function putTriad($v){ - $this->buffer .= Utils::writeTriad($v); + $this->buffer .= Binary::writeTriad($v); } protected function getLTriad(){ - return Utils::readTriad(strrev($this->get(3))); + return Binary::readTriad(strrev($this->get(3))); } protected function putLTriad($v){ - $this->buffer .= strrev(Utils::writeTriad($v)); + $this->buffer .= strrev(Binary::writeTriad($v)); } protected function getByte(){ diff --git a/src/pocketmine/network/protocol/SetEntityDataPacket.php b/src/pocketmine/network/protocol/SetEntityDataPacket.php index 21bcc38c5..b8da893ad 100644 --- a/src/pocketmine/network/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/protocol/SetEntityDataPacket.php @@ -21,6 +21,7 @@ namespace pocketmine\network\protocol; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class SetEntityDataPacket extends DataPacket{ @@ -38,7 +39,7 @@ class SetEntityDataPacket extends DataPacket{ public function encode(){ $this->reset(); $this->putInt($this->eid); - $this->put(Utils::writeMetadata($this->metadata)); + $this->put(Binary::writeMetadata($this->metadata)); } } \ No newline at end of file diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 5fe9b09d9..97210f699 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\query; use pocketmine\Server; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class QueryHandler{ @@ -98,7 +99,7 @@ class QueryHandler{ } public static function getTokenString($token, $salt){ - return Utils::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); + return Binary::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); } public function handle(QueryPacket $packet){ @@ -115,7 +116,7 @@ class QueryHandler{ $this->server->sendPacket($pk); break; case QueryPacket::STATISTICS: //Stat - $token = Utils::readInt(substr($packet->payload, 0, 4)); + $token = Binary::readInt(substr($packet->payload, 0, 4)); if($token !== self::getTokenString($this->token, $packet->ip) and $token !== self::getTokenString($this->lastToken, $packet->ip)){ break; } @@ -130,7 +131,7 @@ class QueryHandler{ } $pk->payload = $this->longData; }else{ - $pk->payload = $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . $this->server->getDefaultLevel()->getName() . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Utils::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00"; + $pk->payload = $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . $this->server->getDefaultLevel()->getName() . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Binary::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00"; } $pk->encode(); $this->server->sendPacket($pk); diff --git a/src/pocketmine/network/query/QueryPacket.php b/src/pocketmine/network/query/QueryPacket.php index adf42a85b..8c560e3d9 100644 --- a/src/pocketmine/network/query/QueryPacket.php +++ b/src/pocketmine/network/query/QueryPacket.php @@ -22,6 +22,7 @@ namespace pocketmine\network\query; use pocketmine\network\Packet; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class QueryPacket extends Packet{ @@ -34,13 +35,13 @@ class QueryPacket extends Packet{ public function decode(){ $this->packetType = ord($this->buffer{2}); - $this->sessionID = Utils::readInt(substr($this->buffer, 3, 4)); + $this->sessionID = Binary::readInt(substr($this->buffer, 3, 4)); $this->payload = substr($this->buffer, 7); } public function encode(){ $this->buffer .= chr($this->packetType); - $this->buffer .= Utils::writeInt($this->sessionID); + $this->buffer .= Binary::writeInt($this->sessionID); $this->buffer .= $this->payload; } } \ No newline at end of file diff --git a/src/pocketmine/network/raknet/Packet.php b/src/pocketmine/network/raknet/Packet.php index 208e6576d..7ef7a7993 100644 --- a/src/pocketmine/network/raknet/Packet.php +++ b/src/pocketmine/network/raknet/Packet.php @@ -78,6 +78,7 @@ use pocketmine\network\protocol\TileEventPacket; use pocketmine\network\protocol\UnknownPacket; use pocketmine\network\protocol\UpdateBlockPacket; use pocketmine\network\protocol\UseItemPacket; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class Packet extends NetworkPacket{ @@ -111,19 +112,19 @@ class Packet extends NetworkPacket{ } private function getLong($unsigned = false){ - return Utils::readLong($this->get(8), $unsigned); + return Binary::readLong($this->get(8), $unsigned); } private function getInt(){ - return Utils::readInt($this->get(4)); + return Binary::readInt($this->get(4)); } private function getShort($unsigned = false){ - return Utils::readShort($this->get(2), $unsigned); + return Binary::readShort($this->get(2), $unsigned); } private function getLTriad(){ - return Utils::readTriad(strrev($this->get(3))); + return Binary::readTriad(strrev($this->get(3))); } private function getByte(){ @@ -506,11 +507,11 @@ class Packet extends NetworkPacket{ ++$pointer; if($type === false){ $payload .= "\x00"; - $payload .= strrev(Utils::writeTriad($start)); - $payload .= strrev(Utils::writeTriad($end)); + $payload .= strrev(Binary::writeTriad($start)); + $payload .= strrev(Binary::writeTriad($end)); }else{ - $payload .= Utils::writeBool(true); - $payload .= strrev(Utils::writeTriad($start)); + $payload .= Binary::writeBool(true); + $payload .= strrev(Binary::writeTriad($start)); } ++$records; } @@ -558,23 +559,23 @@ class Packet extends NetworkPacket{ } protected function putLong($v){ - $this->buffer .= Utils::writeLong($v); + $this->buffer .= Binary::writeLong($v); } protected function putInt($v){ - $this->buffer .= Utils::writeInt($v); + $this->buffer .= Binary::writeInt($v); } protected function putShort($v){ - $this->buffer .= Utils::writeShort($v); + $this->buffer .= Binary::writeShort($v); } protected function putTriad($v){ - $this->buffer .= Utils::writeTriad($v); + $this->buffer .= Binary::writeTriad($v); } protected function putLTriad($v){ - $this->buffer .= strrev(Utils::writeTriad($v)); + $this->buffer .= strrev(Binary::writeTriad($v)); } protected function putByte($v){ diff --git a/src/pocketmine/network/rcon/RCONInstance.php b/src/pocketmine/network/rcon/RCONInstance.php index 4c0420830..cb7ec7197 100644 --- a/src/pocketmine/network/rcon/RCONInstance.php +++ b/src/pocketmine/network/rcon/RCONInstance.php @@ -21,6 +21,7 @@ namespace pocketmine\network\rcon; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class RCONInstance extends \Thread{ @@ -49,11 +50,11 @@ class RCONInstance extends \Thread{ } private function writePacket($client, $requestID, $packetType, $payload){ - $pk = Utils::writeLInt((int) $requestID) - . Utils::writeLInt((int) $packetType) + $pk = Binary::writeLInt((int) $requestID) + . Binary::writeLInt((int) $packetType) . $payload . "\x00\x00"; //Terminate payload and packet - return socket_write($client, Utils::writeLInt(strlen($pk)) . $pk); + return socket_write($client, Binary::writeLInt(strlen($pk)) . $pk); } private function readPacket($client, &$size, &$requestID, &$packetType, &$payload){ @@ -67,12 +68,12 @@ class RCONInstance extends \Thread{ return false; } @socket_set_block($client); - $size = Utils::readLInt($d); + $size = Binary::readLInt($d); if($size < 0 or $size > 65535){ return false; } - $requestID = Utils::readLInt(socket_read($client, 4)); - $packetType = Utils::readLInt(socket_read($client, 4)); + $requestID = Binary::readLInt(socket_read($client, 4)); + $packetType = Binary::readLInt(socket_read($client, 4)); $payload = rtrim(socket_read($client, $size + 2)); //Strip two null bytes return true; } diff --git a/src/pocketmine/pmf/LevelFormat.php b/src/pocketmine/pmf/LevelFormat.php index 4d48a27e0..28f577179 100644 --- a/src/pocketmine/pmf/LevelFormat.php +++ b/src/pocketmine/pmf/LevelFormat.php @@ -25,6 +25,7 @@ use pocketmine\level\Level; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Enum; +use pocketmine\utils\Binary; use pocketmine\utils\Utils; class LevelFormat extends PMF{ @@ -95,18 +96,18 @@ class LevelFormat extends PMF{ @ftruncate($this->fp, 5); $this->seek(5); $this->write(chr($this->levelData["version"])); - $this->write(Utils::writeShort(strlen($this->levelData["name"])) . $this->levelData["name"]); - $this->write(Utils::writeInt($this->levelData["seed"])); - $this->write(Utils::writeInt($this->levelData["time"])); - $this->write(Utils::writeFloat($this->levelData["spawnX"])); - $this->write(Utils::writeFloat($this->levelData["spawnY"])); - $this->write(Utils::writeFloat($this->levelData["spawnZ"])); + $this->write(Binary::writeShort(strlen($this->levelData["name"])) . $this->levelData["name"]); + $this->write(Binary::writeInt($this->levelData["seed"])); + $this->write(Binary::writeInt($this->levelData["time"])); + $this->write(Binary::writeFloat($this->levelData["spawnX"])); + $this->write(Binary::writeFloat($this->levelData["spawnY"])); + $this->write(Binary::writeFloat($this->levelData["spawnZ"])); $this->write(chr($this->levelData["height"])); - $this->write(Utils::writeShort(strlen($this->levelData["generator"])) . $this->levelData["generator"]); + $this->write(Binary::writeShort(strlen($this->levelData["generator"])) . $this->levelData["generator"]); $settings = serialize($this->levelData["generatorSettings"]); - $this->write(Utils::writeShort(strlen($settings)) . $settings); + $this->write(Binary::writeShort(strlen($settings)) . $settings); $extra = zlib_encode($this->levelData["extra"], self::ZLIB_ENCODING, self::ZLIB_LEVEL); - $this->write(Utils::writeShort(strlen($extra)) . $extra); + $this->write(Binary::writeShort(strlen($extra)) . $extra); } private function createBlank(){ @@ -125,12 +126,12 @@ class LevelFormat extends PMF{ return false; } - $this->levelData["name"] = $this->read(Utils::readShort($this->read(2), false)); - $this->levelData["seed"] = Utils::readInt($this->read(4)); - $this->levelData["time"] = Utils::readInt($this->read(4)); - $this->levelData["spawnX"] = Utils::readFloat($this->read(4)); - $this->levelData["spawnY"] = Utils::readFloat($this->read(4)); - $this->levelData["spawnZ"] = Utils::readFloat($this->read(4)); + $this->levelData["name"] = $this->read(Binary::readShort($this->read(2), false)); + $this->levelData["seed"] = Binary::readInt($this->read(4)); + $this->levelData["time"] = Binary::readInt($this->read(4)); + $this->levelData["spawnX"] = Binary::readFloat($this->read(4)); + $this->levelData["spawnY"] = Binary::readFloat($this->read(4)); + $this->levelData["spawnZ"] = Binary::readFloat($this->read(4)); if($this->levelData["version"] === 0){ $this->read(1); $this->levelData["height"] = ord($this->read(1)); @@ -139,11 +140,11 @@ class LevelFormat extends PMF{ if($this->levelData["height"] !== 8){ return false; } - $this->levelData["generator"] = $this->read(Utils::readShort($this->read(2), false)); - $this->levelData["generatorSettings"] = unserialize($this->read(Utils::readShort($this->read(2), false))); + $this->levelData["generator"] = $this->read(Binary::readShort($this->read(2), false)); + $this->levelData["generatorSettings"] = unserialize($this->read(Binary::readShort($this->read(2), false))); } - $this->levelData["extra"] = @zlib_decode($this->read(Utils::readShort($this->read(2), false))); + $this->levelData["extra"] = @zlib_decode($this->read(Binary::readShort($this->read(2), false))); $upgrade = false; if($this->levelData["version"] === 0){ @@ -166,7 +167,7 @@ class LevelFormat extends PMF{ $X = $index & 0x0F; $Z = $index >> 4; - $bitflags = Utils::readShort($this->read(2)); + $bitflags = Binary::readShort($this->read(2)); $oldPath = dirname($this->file) . "/chunks/" . $Z . "." . $X . ".pmc"; $chunkOld = gzopen($oldPath, "rb"); $newPath = dirname($this->file) . "/chunks/" . (($X ^ $Z) & 0xff) . "/" . $Z . "." . $X . ".pmc"; @@ -196,7 +197,7 @@ class LevelFormat extends PMF{ $nbtCodec = new NBT(NBT::BIG_ENDIAN); $nbtCodec->setData($nbt); $namedtag = $nbtCodec->write(); - $namedtag = Utils::writeInt(strlen($namedtag)) . $namedtag; + $namedtag = Binary::writeInt(strlen($namedtag)) . $namedtag; foreach(glob(dirname($this->file) . "/chunks/*/*.*.pmc") as $chunkFile){ $oldChunk = zlib_decode(file_get_contents($chunkFile)); $newChunk = substr($oldChunk, 0, 5); @@ -291,10 +292,10 @@ class LevelFormat extends PMF{ $this->chunkInfo[$index] = array( 0 => ord($chunk{0}), - 1 => Utils::readInt(substr($chunk, 1, 4)), + 1 => Binary::readInt(substr($chunk, 1, 4)), ); $offset += 5; - $len = Utils::readInt(substr($chunk, $offset, 4)); + $len = Binary::readInt(substr($chunk, $offset, 4)); $offset += 4; $nbt = new NBT(NBT::BIG_ENDIAN); $nbt->read(substr($chunk, $offset, $len)); @@ -705,11 +706,11 @@ class LevelFormat extends PMF{ $this->chunkChange[$index][-1] = false; $chunk = ""; $chunk .= chr($bitmap); - $chunk .= Utils::writeInt($this->chunkInfo[$index][1]); + $chunk .= Binary::writeInt($this->chunkInfo[$index][1]); $namedtag = new NBT(NBT::BIG_ENDIAN); $namedtag->setData($this->chunkInfo[$index][2]); $namedtag = $namedtag->write(); - $chunk .= Utils::writeInt(strlen($namedtag)) . $namedtag; + $chunk .= Binary::writeInt(strlen($namedtag)) . $namedtag; $chunk .= $this->chunkInfo[$index][3]; //biomes for($Y = 0; $Y < 8; ++$Y){ $t = 1 << $Y; diff --git a/src/pocketmine/utils/Binary.php b/src/pocketmine/utils/Binary.php new file mode 100644 index 000000000..a6013da07 --- /dev/null +++ b/src/pocketmine/utils/Binary.php @@ -0,0 +1,469 @@ + $d){ + $m .= chr(($d[0] << 5) | ($bottom & 0b00011111)); + switch($d[0]){ + case 0: + $m .= self::writeByte($d[1]); + break; + case 1: + $m .= self::writeLShort($d[1]); + break; + case 2: + $m .= self::writeLInt($d[1]); + break; + case 3: + $m .= self::writeLFloat($d[1]); + break; + case 4: + $m .= self::writeLShort(strlen($d[1])); + $m .= $data[1]; + break; + case 5: + $m .= self::writeLShort($d[1][0]); + $m .= self::writeByte($d[1][1]); + $m .= self::writeLShort($d[1][2]); + break; + case 6: + for($i = 0; $i < 3; ++$i){ + $m .= self::writeLInt($d[1][$i]); + } + break; + } + } + $m .= "\x7f"; + + return $m; + } + + /** + * Writes a Item to binary (short id, byte Count, short Damage) + * + * @param Item $item + * + * @return string + */ + public static function writeSlot(Item $item){ + return self::writeShort($item->getID()) . chr($item->getCount()) . self::writeShort($item->getMetadata()); + } + + /** + * Reads a binary Item, returns an Item object + * + * @param object $ob + * + * @return Item + */ + + public static function readSlot($ob){ + $id = self::readShort($ob->get(2)); + $cnt = ord($ob->get(1)); + + return Item::get( + $id, + self::readShort($ob->get(2)), + $cnt + ); + } + + /** + * Reads a metadata coded string + * TODO: Change + * + * @param $value + * @param bool $types + * + * @return array + */ + public static function readMetadata($value, $types = false){ + $offset = 0; + $m = array(); + $b = ord($value{$offset}); + ++$offset; + while($b !== 127 and isset($value{$offset})){ + $bottom = $b & 0x1F; + $type = $b >> 5; + switch($type){ + case 0: + $r = self::readByte($value{$offset}); + ++$offset; + break; + case 1: + $r = self::readLShort(substr($value, $offset, 2)); + $offset += 2; + break; + case 2: + $r = self::readLInt(substr($value, $offset, 4)); + $offset += 4; + break; + case 3: + $r = self::readLFloat(substr($value, $offset, 4)); + $offset += 4; + break; + case 4: + $len = self::readLShort(substr($value, $offset, 2)); + $offset += 2; + $r = substr($value, $offset, $len); + $offset += $len; + break; + case 5: + $r = array(); + $r[] = self::readLShort(substr($value, $offset, 2)); + $offset += 2; + $r[] = ord($value{$offset}); + ++$offset; + $r[] = self::readLShort(substr($value, $offset, 2)); + $offset += 2; + break; + case 6: + $r = array(); + for($i = 0; $i < 3; ++$i){ + $r[] = self::readLInt(substr($value, $offset, 4)); + $offset += 4; + } + break; + + } + if($types === true){ + $m[$bottom] = array($r, $type); + }else{ + $m[$bottom] = $r; + } + $b = ord($value{$offset}); + ++$offset; + } + + return $m; + } + + public static function readDataArray($str, $len = 10, &$offset = null){ + $data = array(); + $offset = 0; + for($i = 1; $i <= $len and isset($str{$offset}); ++$i){ + $l = self::readTriad(substr($str, $offset, 3)); + $offset += 3; + $data[] = substr($str, $offset, $l); + $offset += $l; + } + + return $data; + } + + public static function writeDataArray($data){ + $raw = ""; + foreach($data as $v){ + $raw .= self::writeTriad(strlen($v)); + $raw .= $v; + } + + return $raw; + } + + /** + * Reads a byte boolean + * + * @param $b + * + * @return bool + */ + public static function readBool($b){ + return self::readByte($b, false) === 0 ? false : true; + } + + /** + * Writes a byte boolean + * + * @param $b + * + * @return bool|string + */ + public static function writeBool($b){ + return self::writeByte($b === true ? 1 : 0); + } + + /** + * Reads an unsigned/signed byte + * + * @param $c + * @param bool $signed + * + * @return int + */ + public static function readByte($c, $signed = true){ + $b = ord($c{0}); + if($signed === true and ($b & 0x80) === 0x80){ //calculate Two's complement + $b = -0x80 + ($b & 0x7f); + } + + return $b; + } + + /** + * Writes an unsigned/signed byte + * + * @param $c + * + * @return bool|string + */ + public static function writeByte($c){ + if($c > 0xff){ + return false; + } + if($c < 0 and $c >= -0x80){ + $c = 0xff + $c + 1; + } + + return chr($c); + } + + /** + * Reads a 16-bit signed/unsigned big-endian number + * + * @param $str + * @param bool $signed + * + * @return int + */ + public static function readShort($str, $signed = true){ + list(, $unpacked) = @unpack("n", $str); + if($unpacked > 0x7fff and $signed === true){ + $unpacked -= 0x10000; // Convert unsigned short to signed short + } + + return $unpacked; + } + + /** + * Writes a 16-bit signed/unsigned big-endian number + * + * @param $value + * + * @return string + */ + public static function writeShort($value){ + if($value < 0){ + $value += 0x10000; + } + + return pack("n", $value); + } + + /** + * Reads a 16-bit signed/unsigned little-endian number + * + * @param $str + * @param bool $signed + * + * @return int + */ + public static function readLShort($str, $signed = true){ + list(, $unpacked) = @unpack("v", $str); + if($unpacked > 0x7fff and $signed === true){ + $unpacked -= 0x10000; // Convert unsigned short to signed short + } + + return $unpacked; + } + + /** + * Writes a 16-bit signed/unsigned little-endian number + * + * @param $value + * + * @return string + */ + public static function writeLShort($value){ + if($value < 0){ + $value += 0x10000; + } + + return pack("v", $value); + } + + public static function readInt($str){ + list(, $unpacked) = @unpack("N", $str); + if($unpacked > 2147483647){ + $unpacked -= 4294967296; + } + + return (int) $unpacked; + } + + public static function writeInt($value){ + return pack("N", $value); + } + + public static function readLInt($str){ + list(, $unpacked) = @unpack("V", $str); + if($unpacked >= 2147483648){ + $unpacked -= 4294967296; + } + + return (int) $unpacked; + } + + public static function writeLInt($value){ + return pack("V", $value); + } + + public static function readFloat($str){ + list(, $value) = ENDIANNESS === self::BIG_ENDIAN ? @unpack("f", $str) : @unpack("f", strrev($str)); + + return $value; + } + + public static function writeFloat($value){ + return ENDIANNESS === self::BIG_ENDIAN ? pack("f", $value) : strrev(pack("f", $value)); + } + + public static function readLFloat($str){ + list(, $value) = ENDIANNESS === self::BIG_ENDIAN ? @unpack("f", strrev($str)) : @unpack("f", $str); + + return $value; + } + + public static function writeLFloat($value){ + return ENDIANNESS === self::BIG_ENDIAN ? strrev(pack("f", $value)) : pack("f", $value); + } + + public static function printFloat($value){ + return preg_replace("/(\.\d+?)0+$/", "$1", sprintf("%F", $value)); + } + + public static function readDouble($str){ + list(, $value) = ENDIANNESS === self::BIG_ENDIAN ? @unpack("d", $str) : @unpack("d", strrev($str)); + + return $value; + } + + public static function writeDouble($value){ + return ENDIANNESS === self::BIG_ENDIAN ? pack("d", $value) : strrev(pack("d", $value)); + } + + public static function readLDouble($str){ + list(, $value) = ENDIANNESS === self::BIG_ENDIAN ? @unpack("d", strrev($str)) : @unpack("d", $str); + + return $value; + } + + public static function writeLDouble($value){ + return ENDIANNESS === self::BIG_ENDIAN ? strrev(pack("d", $value)) : pack("d", $value); + } + + public static function readLong($x, $signed = true){ + $value = "0"; + if($signed === true){ + $negative = ((ord($x{0}) & 0x80) === 0x80) ? true : false; + if($negative){ + $x = ~$x; + } + }else{ + $negative = false; + } + + for($i = 0; $i < 8; $i += 4){ + $value = bcmul($value, "4294967296", 0); //4294967296 == 2^32 + $value = bcadd($value, 0x1000000 * ord(@$x{$i}) + ((ord(@$x{$i + 1}) << 16) | (ord(@$x{$i + 2}) << 8) | ord(@$x{$i + 3})), 0); + } + + return ($negative === true ? "-" . $value : $value); + } + + public static function writeLong($value){ + $x = ""; + if($value{0} === "-"){ + $negative = true; + $value = bcadd($value, "1"); + if($value{0} === "-"){ + $value = substr($value, 1); + } + }else{ + $negative = false; + } + while(bccomp($value, "0", 0) > 0){ + $temp = bcmod($value, "16777216"); + $x = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $x; + $value = bcdiv($value, "16777216", 0); + } + $x = str_pad(substr($x, 0, 8), 8, "\x00", STR_PAD_LEFT); + if($negative === true){ + $x = ~$x; + } + + return $x; + } + + public static function readLLong($str){ + return self::readLong(strrev($str)); + } + + public static function writeLLong($value){ + return strrev(self::writeLong($value)); + } + +} \ No newline at end of file diff --git a/src/pocketmine/utils/Random.php b/src/pocketmine/utils/Random.php index b688fa392..618f8d910 100644 --- a/src/pocketmine/utils/Random.php +++ b/src/pocketmine/utils/Random.php @@ -39,7 +39,7 @@ class Random{ * @param int|bool $seed Integer to be used as seed. If false, generates a Random one */ public function setSeed($seed = false){ - $seed = $seed !== false ? (int) $seed : Utils::readInt(Utils::getRandomBytes(4, false)); + $seed = $seed !== false ? (int) $seed : Binary::readInt(Utils::getRandomBytes(4, false)); $this->z = $seed ^ 0xdeadbeef; $this->w = $seed ^ 0xc0de1337; } @@ -50,7 +50,7 @@ class Random{ * @return int */ public function nextInt(){ - return Utils::readInt($this->nextBytes(4)) & 0x7FFFFFFF; + return Binary::readInt($this->nextBytes(4)) & 0x7FFFFFFF; } /** @@ -59,7 +59,7 @@ class Random{ * @return int */ public function nextSignedInt(){ - return Utils::readInt($this->nextBytes(4)); + return Binary::readInt($this->nextBytes(4)); } /** diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 815df6b98..5c083e45d 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -30,10 +30,6 @@ use pocketmine\item\Item; * Big collection of functions */ class Utils{ - const BIG_ENDIAN = 0x00; - const LITTLE_ENDIAN = 0x01; - - public static $online = true; public static $ip = false; @@ -201,199 +197,6 @@ class Utils{ return preg_replace('#([^\x20-\x7E])#', '.', $str); } - /** - * Reads a 3-byte big-endian number - * - * @param $str - * - * @return mixed - */ - public static function readTriad($str){ - list(, $unpacked) = @unpack("N", "\x00" . $str); - - return $unpacked; - } - - /** - * Writes a 3-byte big-endian number - * - * @param $value - * - * @return string - */ - public static function writeTriad($value){ - return substr(pack("N", $value), 1); - } - - /** - * Writes a coded metadata string - * TODO: Replace and move this to entity - * - * @param $data - * - * @return string - */ - public static function writeMetadata($data){ - $m = ""; - foreach($data as $bottom => $d){ - $m .= chr(($d["type"] << 5) | ($bottom & 0b00011111)); - switch($d["type"]){ - case 0: - $m .= Utils::writeByte($d["value"]); - break; - case 1: - $m .= Utils::writeLShort($d["value"]); - break; - case 2: - $m .= Utils::writeLInt($d["value"]); - break; - case 3: - $m .= Utils::writeLFloat($d["value"]); - break; - case 4: - $m .= Utils::writeLShort(strlen($d["value"])); - $m .= $data["value"]; - break; - case 5: - $m .= Utils::writeLShort($d["value"][0]); - $m .= Utils::writeByte($d["value"][1]); - $m .= Utils::writeLShort($d["value"][2]); - break; - case 6: - for($i = 0; $i < 3; ++$i){ - $m .= Utils::writeLInt($d["value"][$i]); - } - break; - } - } - $m .= "\x7f"; - - return $m; - } - - /** - * Writes a Item to binary (short id, byte Count, short Damage) - * - * @param Item $item - * - * @return string - */ - public static function writeSlot(Item $item){ - return Utils::writeShort($item->getID()) . chr($item->getCount()) . Utils::writeShort($item->getMetadata()); - } - - /** - * Reads a binary Item, returns an Item object - * - * @param $ob - * - * @return Item - */ - - public static function readSlot($ob){ - $id = Utils::readShort($ob->get(2)); - $cnt = ord($ob->get(1)); - - return Item::get( - $id, - Utils::readShort($ob->get(2)), - $cnt - ); - } - - /** - * Reads a metadata coded string - * TODO: Change - * - * @param $value - * @param bool $types - * - * @return array - */ - public static function readMetadata($value, $types = false){ - $offset = 0; - $m = array(); - $b = ord($value{$offset}); - ++$offset; - while($b !== 127 and isset($value{$offset})){ - $bottom = $b & 0x1F; - $type = $b >> 5; - switch($type){ - case 0: - $r = Utils::readByte($value{$offset}); - ++$offset; - break; - case 1: - $r = Utils::readLShort(substr($value, $offset, 2)); - $offset += 2; - break; - case 2: - $r = Utils::readLInt(substr($value, $offset, 4)); - $offset += 4; - break; - case 3: - $r = Utils::readLFloat(substr($value, $offset, 4)); - $offset += 4; - break; - case 4: - $len = Utils::readLShort(substr($value, $offset, 2)); - $offset += 2; - $r = substr($value, $offset, $len); - $offset += $len; - break; - case 5: - $r = array(); - $r[] = Utils::readLShort(substr($value, $offset, 2)); - $offset += 2; - $r[] = ord($value{$offset}); - ++$offset; - $r[] = Utils::readLShort(substr($value, $offset, 2)); - $offset += 2; - break; - case 6: - $r = array(); - for($i = 0; $i < 3; ++$i){ - $r[] = Utils::readLInt(substr($value, $offset, 4)); - $offset += 4; - } - break; - - } - if($types === true){ - $m[$bottom] = array($r, $type); - }else{ - $m[$bottom] = $r; - } - $b = ord($value{$offset}); - ++$offset; - } - - return $m; - } - - public static function readDataArray($str, $len = 10, &$offset = null){ - $data = array(); - $offset = 0; - for($i = 1; $i <= $len and isset($str{$offset}); ++$i){ - $l = Utils::readTriad(substr($str, $offset, 3)); - $offset += 3; - $data[] = substr($str, $offset, $l); - $offset += $l; - } - - return $data; - } - - public static function writeDataArray($data){ - $raw = ""; - foreach($data as $v){ - $raw .= Utils::writeTriad(strlen($v)); - $raw .= $v; - } - - return $raw; - } - /** * This function tries to get all the entropy available in PHP, and distills it to get a good RNG. * @@ -578,249 +381,4 @@ class Utils{ return $ret; } - /** - * Reads a byte boolean - * - * @param $b - * - * @return bool - */ - public static function readBool($b){ - return Utils::readByte($b, false) === 0 ? false : true; - } - - /** - * Writes a byte boolean - * - * @param $b - * - * @return bool|string - */ - public static function writeBool($b){ - return Utils::writeByte($b === true ? 1 : 0); - } - - /** - * Reads an unsigned/signed byte - * - * @param $c - * @param bool $signed - * - * @return int - */ - public static function readByte($c, $signed = true){ - $b = ord($c{0}); - if($signed === true and ($b & 0x80) === 0x80){ //calculate Two's complement - $b = -0x80 + ($b & 0x7f); - } - - return $b; - } - - /** - * Writes an unsigned/signed byte - * - * @param $c - * - * @return bool|string - */ - public static function writeByte($c){ - if($c > 0xff){ - return false; - } - if($c < 0 and $c >= -0x80){ - $c = 0xff + $c + 1; - } - - return chr($c); - } - - /** - * Reads a 16-bit signed/unsigned big-endian number - * - * @param $str - * @param bool $signed - * - * @return int - */ - public static function readShort($str, $signed = true){ - list(, $unpacked) = @unpack("n", $str); - if($unpacked > 0x7fff and $signed === true){ - $unpacked -= 0x10000; // Convert unsigned short to signed short - } - - return $unpacked; - } - - /** - * Writes a 16-bit signed/unsigned big-endian number - * - * @param $value - * - * @return string - */ - public static function writeShort($value){ - if($value < 0){ - $value += 0x10000; - } - - return pack("n", $value); - } - - /** - * Reads a 16-bit signed/unsigned little-endian number - * - * @param $str - * @param bool $signed - * - * @return int - */ - public static function readLShort($str, $signed = true){ - list(, $unpacked) = @unpack("v", $str); - if($unpacked > 0x7fff and $signed === true){ - $unpacked -= 0x10000; // Convert unsigned short to signed short - } - - return $unpacked; - } - - /** - * Writes a 16-bit signed/unsigned little-endian number - * - * @param $value - * - * @return string - */ - public static function writeLShort($value){ - if($value < 0){ - $value += 0x10000; - } - - return pack("v", $value); - } - - public static function readInt($str){ - list(, $unpacked) = @unpack("N", $str); - if($unpacked > 2147483647){ - $unpacked -= 4294967296; - } - - return (int) $unpacked; - } - - public static function writeInt($value){ - return pack("N", $value); - } - - public static function readLInt($str){ - list(, $unpacked) = @unpack("V", $str); - if($unpacked >= 2147483648){ - $unpacked -= 4294967296; - } - - return (int) $unpacked; - } - - public static function writeLInt($value){ - return pack("V", $value); - } - - public static function readFloat($str){ - list(, $value) = ENDIANNESS === Utils::BIG_ENDIAN ? @unpack("f", $str) : @unpack("f", strrev($str)); - - return $value; - } - - public static function writeFloat($value){ - return ENDIANNESS === Utils::BIG_ENDIAN ? pack("f", $value) : strrev(pack("f", $value)); - } - - public static function readLFloat($str){ - list(, $value) = ENDIANNESS === Utils::BIG_ENDIAN ? @unpack("f", strrev($str)) : @unpack("f", $str); - - return $value; - } - - public static function writeLFloat($value){ - return ENDIANNESS === Utils::BIG_ENDIAN ? strrev(pack("f", $value)) : pack("f", $value); - } - - public static function printFloat($value){ - return preg_replace("/(\.\d+?)0+$/", "$1", sprintf("%F", $value)); - } - - public static function readDouble($str){ - list(, $value) = ENDIANNESS === Utils::BIG_ENDIAN ? @unpack("d", $str) : @unpack("d", strrev($str)); - - return $value; - } - - public static function writeDouble($value){ - return ENDIANNESS === Utils::BIG_ENDIAN ? pack("d", $value) : strrev(pack("d", $value)); - } - - public static function readLDouble($str){ - list(, $value) = ENDIANNESS === Utils::BIG_ENDIAN ? @unpack("d", strrev($str)) : @unpack("d", $str); - - return $value; - } - - public static function writeLDouble($value){ - return ENDIANNESS === Utils::BIG_ENDIAN ? strrev(pack("d", $value)) : pack("d", $value); - } - - public static function readLong($x, $signed = true){ - $value = "0"; - if($signed === true){ - $negative = ((ord($x{0}) & 0x80) === 0x80) ? true : false; - if($negative){ - $x = ~$x; - } - }else{ - $negative = false; - } - - for($i = 0; $i < 8; $i += 4){ - $value = bcmul($value, "4294967296", 0); //4294967296 == 2^32 - $value = bcadd($value, 0x1000000 * ord(@$x{$i}) + ((ord(@$x{$i + 1}) << 16) | (ord(@$x{$i + 2}) << 8) | ord(@$x{$i + 3})), 0); - } - - return ($negative === true ? "-" . $value : $value); - } - - public static function writeLong($value){ - $x = ""; - if($value{0} === "-"){ - $negative = true; - $value = bcadd($value, "1"); - if($value{0} === "-"){ - $value = substr($value, 1); - } - }else{ - $negative = false; - } - while(bccomp($value, "0", 0) > 0){ - $temp = bcmod($value, "16777216"); - $x = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $x; - $value = bcdiv($value, "16777216", 0); - } - $x = str_pad(substr($x, 0, 8), 8, "\x00", STR_PAD_LEFT); - if($negative === true){ - $x = ~$x; - } - - return $x; - } - - public static function readLLong($str){ - return Utils::readLong(strrev($str)); - } - - public static function writeLLong($value){ - return strrev(Utils::writeLong($value)); - } - - -} - -@define("pocketmine\\utils\\ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Utils::BIG_ENDIAN : Utils::LITTLE_ENDIAN)); \ No newline at end of file +} \ No newline at end of file diff --git a/src/tests/ServerSuiteTest.php b/src/tests/ServerSuiteTest.php index 17aa965d3..5acb62d54 100644 --- a/src/tests/ServerSuiteTest.php +++ b/src/tests/ServerSuiteTest.php @@ -42,11 +42,11 @@ if(!class_exists("\\pocketmine\\Server", false)){ class ServerSuiteTest{ public function __construct(){ //binary things - testCase("Utils\\Utils::readTriad", Utils\Utils::readTriad("\x02\x01\x03"), 131331); - testCase("Utils\\Utils::readInt", Utils\Utils::readInt("\xff\x02\x01\x03"), -16645885); - testCase("Utils\\Utils::readFloat", abs(Utils\Utils::readFloat("\x49\x02\x01\x03") - 532496.1875) < 0.0001, true); - testCase("Utils\\Utils::readDouble", abs(Utils\Utils::readDouble("\x41\x02\x03\x04\x05\x06\x07\x08") - 147552.5024529) < 0.0001, true); - testCase("Utils\\Utils::readTriad", Utils\Utils::readLong("\x41\x02\x03\x04\x05\x06\x07\x08"), "4684309878217770760"); + testCase("Utils\\Binary::readTriad", Utils\Binary::readTriad("\x02\x01\x03"), 131331); + testCase("Utils\\Binary::readInt", Utils\Binary::readInt("\xff\x02\x01\x03"), -16645885); + testCase("Utils\\Binary::readFloat", abs(Utils\Binary::readFloat("\x49\x02\x01\x03") - 532496.1875) < 0.0001, true); + testCase("Utils\\Binary::readDouble", abs(Utils\Binary::readDouble("\x41\x02\x03\x04\x05\x06\x07\x08") - 147552.5024529) < 0.0001, true); + testCase("Utils\\Binary::readTriad", Utils\Binary::readLong("\x41\x02\x03\x04\x05\x06\x07\x08"), "4684309878217770760"); //PocketMine-MP server startup global $server;