Moved binary methods from Utils to Binary

This commit is contained in:
Shoghi Cervantes 2014-04-07 13:54:07 +02:00
parent ac02185ad0
commit c0de004472
25 changed files with 894 additions and 546 deletions

View File

@ -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

View File

@ -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:

View File

@ -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"])){

View File

@ -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"),

View File

@ -21,6 +21,7 @@
namespace pocketmine\level;
use pocketmine\level\format\PocketChunkParser;
use pocketmine\nbt\NBT;
use pocketmine\pmf\LevelFormat;
use pocketmine\utils\Config;

View File

@ -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 . "/";

View File

@ -0,0 +1,90 @@
<?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/
*
*
*/
namespace pocketmine\level\format;
interface Chunk{
/**
* @return int
*/
public function getX();
/**
* @return int
*/
public function getZ();
/**
* @return \pocketmine\level\Level
*/
public function getLevel();
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return \pocketmine\block\Block
*/
public function getBlock($x, $y, $z);
/**
* Thread-safe read-only chunk
*
* @return ChunkSnapShot
*/
public function getChunkSnapshot();
/**
* @return \pocketmine\entity\Entity[]
*/
public function getEntities();
/**
* @return \pocketmine\tile\Tile[]
*/
public function getTiles();
/**
* @return bool
*/
public function isLoaded();
/**
* Loads the chunk
*
* @param bool $generate If the chunk does not exist, generate it
*
* @return bool
*/
public function load($generate = true);
/**
* @param bool $save
* @param bool $safe If false, unload the chunk even if players are nearby
*
* @return bool
*/
public function unload($save = true, $safe = true);
}

View File

@ -0,0 +1,111 @@
<?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/
*
*
*/
namespace pocketmine\level\format;
interface ChunkSnapshot{
/**
* @return int
*/
public function getX();
/**
* @return int
*/
public function getZ();
/**
* @return string
*/
public function getLevelName();
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return int 0-255
*/
public function getBlockId($x, $y, $z);
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return int 0-15
*/
public function getBlockData($x, $y, $z);
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return int 0-15
*/
public function getBlockSkyLight($x, $y, $z);
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return int 0-15
*/
public function getBlockEmittedLight($x, $y, $z);
/**
* @param int $x 0-15
* @param int $y 0-127
* @param int $z 0-15
*
* @return int 0-15
*/
public function getBlockLight($x, $y, $z);
/**
* @param int $x 0-15
* @param int $z 0-15
*
* @return int 0-127
*/
public function getHighestBlockAt($x, $z);
/**
* @param int $x 0-15
* @param int $z 0-15
*
* @return int
*/
public function getBiome($x, $z);
/**
* Tests whether a section (mini-chunk) is empty
*
* @param $fY 0-7, (Y / 16)
*
* @return bool
*/
public function isSectionEmpty($fY);
}

View File

@ -0,0 +1,67 @@
<?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/
*
*
*/
namespace pocketmine\level\format;
/**
* All Level formats must implement this interface
*/
interface LevelFormat{
/**
* @param string $path
* @param string $levelName
*/
public function __construct($path, $levelName);
/**
* Tells if the path is a valid level
*
* @param string $path
*
* @return true
*/
public static function isValid($path);
/**
* @param int $X absolute Chunk X value
* @param int $Z absolute Chunk Z value
* @param bool $create Whether to generate the chunk if it does not exist
*
* @return ChunkSnapshot
*/
public function getChunk($X, $Z, $create = false);
/**
* @return bool
*/
public function saveChunks();
public function unloadChunks();
public function getName();
/**
* @return ChunkSnapshot
*/
public function getLoadedChunks();
}

View File

@ -19,8 +19,9 @@
*
*/
namespace pocketmine\level;
namespace pocketmine\level\format;
use pocketmine\utils\Binary;
use pocketmine\utils\Utils;
/**
@ -43,7 +44,7 @@ class PocketChunkParser{
$this->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

View File

@ -0,0 +1,36 @@
<?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/
*
*
*/
namespace pocketmine\level\format\anvil;
use pocketmine\level\format\LevelFormat;
class Anvil implements LevelFormat{
protected $basePath;
public function __construct($path, $levelName){
$this->basePath = realpath($path) . "/";
}
public static function isValid($path){
return file_exists(realpath($path) . "region/");
}
}

View File

@ -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(){

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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(){

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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){

View File

@ -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;
}

View File

@ -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;

View File

@ -0,0 +1,469 @@
<?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/
*
*
*/
/**
* Various Utilities used around the code
*/
namespace pocketmine\utils;
use pocketmine\item\Item;
class Binary{
const BIG_ENDIAN = 0x00;
const LITTLE_ENDIAN = 0x01;
/**
* 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[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));
}
}

View File

@ -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));
}
/**

View File

@ -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));
}

View File

@ -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;