mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-13 13:25:16 +00:00
Initial spawn on 0.16
This commit is contained in:
parent
bb9ab525b6
commit
dd0c5efb56
@ -132,9 +132,9 @@ use pocketmine\plugin\Plugin;
|
|||||||
use pocketmine\tile\Sign;
|
use pocketmine\tile\Sign;
|
||||||
use pocketmine\tile\Spawnable;
|
use pocketmine\tile\Spawnable;
|
||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
use pocketmine\utils\UUID;
|
use pocketmine\utils\UUID;
|
||||||
use raklib\Binary;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1689,17 +1689,26 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$spawnPosition = $this->getSpawn();
|
$spawnPosition = $this->getSpawn();
|
||||||
|
|
||||||
$pk = new StartGamePacket();
|
$pk = new StartGamePacket();
|
||||||
$pk->seed = -1;
|
$pk->entityUniqueId = 0;
|
||||||
$pk->dimension = 0;
|
$pk->entityRuntimeId = 0;
|
||||||
$pk->x = $this->x;
|
$pk->x = $this->x;
|
||||||
$pk->y = $this->y;
|
$pk->y = $this->y;
|
||||||
$pk->z = $this->z;
|
$pk->z = $this->z;
|
||||||
$pk->spawnX = (int) $spawnPosition->x;
|
$pk->seed = -1;
|
||||||
$pk->spawnY = (int) $spawnPosition->y;
|
$pk->dimension = 0; //TODO: implement this properly
|
||||||
$pk->spawnZ = (int) $spawnPosition->z;
|
|
||||||
$pk->generator = 1; //0 old, 1 infinite, 2 flat
|
|
||||||
$pk->gamemode = $this->gamemode & 0x01;
|
$pk->gamemode = $this->gamemode & 0x01;
|
||||||
$pk->eid = 0; //Always use EntityID as zero for the actual player
|
$pk->difficulty = $this->server->getDifficulty();
|
||||||
|
$pk->spawnX = $spawnPosition->getFloorX();
|
||||||
|
$pk->spawnY = $spawnPosition->getFloorY();
|
||||||
|
$pk->spawnZ = $spawnPosition->getFloorZ();
|
||||||
|
$pk->hasBeenLoadedInCreative = 1;
|
||||||
|
$pk->dayCycleStopTime = -1; //TODO: implement this properly
|
||||||
|
$pk->eduMode = 0;
|
||||||
|
$pk->rainLevel = 0; //TODO: implement these properly
|
||||||
|
$pk->lightningLevel = 0;
|
||||||
|
$pk->commandsEnabled = 0;
|
||||||
|
$pk->unknown = "UNKNOWN";
|
||||||
|
$pk->worldName = $this->server->getMotd();
|
||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
|
|
||||||
$pk = new SetTimePacket();
|
$pk = new SetTimePacket();
|
||||||
@ -1707,20 +1716,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$pk->started = $this->level->stopTime == false;
|
$pk->started = $this->level->stopTime == false;
|
||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
|
|
||||||
$pk = new SetSpawnPositionPacket();
|
|
||||||
$pk->x = (int) $spawnPosition->x;
|
|
||||||
$pk->y = (int) $spawnPosition->y;
|
|
||||||
$pk->z = (int) $spawnPosition->z;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
|
|
||||||
$pk = new SetHealthPacket();
|
$pk = new SetHealthPacket();
|
||||||
$pk->health = $this->getHealth();
|
$pk->health = $this->getHealth();
|
||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
|
|
||||||
$pk = new SetDifficultyPacket();
|
|
||||||
$pk->difficulty = $this->server->getDifficulty();
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
|
|
||||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
|
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
|
||||||
TextFormat::AQUA . $this->username . TextFormat::WHITE,
|
TextFormat::AQUA . $this->username . TextFormat::WHITE,
|
||||||
$this->ip,
|
$this->ip,
|
||||||
@ -3504,7 +3503,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$pk->encode();
|
$pk->encode();
|
||||||
|
|
||||||
$batch = new BatchPacket();
|
$batch = new BatchPacket();
|
||||||
$batch->payload = zlib_encode(Binary::writeInt(strlen($pk->getBuffer())) . $pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
|
$batch->payload = zlib_encode(Binary::writeUnsignedVarInt(strlen($pk->getBuffer())) . $pk->getBuffer(), ZLIB_ENCODING_DEFLATE, Server::getInstance()->networkCompressionLevel);
|
||||||
|
|
||||||
$batch->encode();
|
$batch->encode();
|
||||||
$batch->isEncoded = true;
|
$batch->isEncoded = true;
|
||||||
|
@ -75,8 +75,8 @@ namespace pocketmine {
|
|||||||
const VERSION = "1.6dev";
|
const VERSION = "1.6dev";
|
||||||
const API_VERSION = "2.0.0";
|
const API_VERSION = "2.0.0";
|
||||||
const CODENAME = "Unleashed";
|
const CODENAME = "Unleashed";
|
||||||
const MINECRAFT_VERSION = "v0.15.10.0 alpha";
|
const MINECRAFT_VERSION = "v0.15.90.7 alpha";
|
||||||
const MINECRAFT_VERSION_NETWORK = "0.15.10.0";
|
const MINECRAFT_VERSION_NETWORK = "0.15.90.7";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Startup code. Do not look at it, it may harm you.
|
* Startup code. Do not look at it, it may harm you.
|
||||||
|
@ -1798,9 +1798,9 @@ class Server{
|
|||||||
if(!$p->isEncoded){
|
if(!$p->isEncoded){
|
||||||
$p->encode();
|
$p->encode();
|
||||||
}
|
}
|
||||||
$str .= Binary::writeInt(strlen($p->buffer)) . $p->buffer;
|
$str .= Binary::writeUnsignedVarInt(strlen($p->buffer)) . $p->buffer;
|
||||||
}else{
|
}else{
|
||||||
$str .= Binary::writeInt(strlen($p)) . $p;
|
$str .= Binary::writeUnsignedVarInt(strlen($p)) . $p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ use pocketmine\network\protocol\UseItemPacket;
|
|||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
|
use pocketmine\utils\BinaryStream;
|
||||||
|
|
||||||
class Network{
|
class Network{
|
||||||
|
|
||||||
@ -209,17 +210,19 @@ class Network{
|
|||||||
|
|
||||||
public function processBatch(BatchPacket $packet, Player $p){
|
public function processBatch(BatchPacket $packet, Player $p){
|
||||||
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
||||||
$len = strlen($str);
|
|
||||||
$offset = 0;
|
|
||||||
try{
|
try{
|
||||||
while($offset < $len){
|
$len = strlen($str);
|
||||||
$pkLen = Binary::readInt(substr($str, $offset, 4));
|
|
||||||
$offset += 4;
|
|
||||||
|
|
||||||
$buf = substr($str, $offset, $pkLen);
|
if($len === 0){
|
||||||
$offset += $pkLen;
|
throw new \InvalidStateException("Empty or invalid BatchPacket received");
|
||||||
|
}
|
||||||
|
|
||||||
if(($pk = $this->getPacket(ord($buf{0}))) !== null){ // #blameshoghi
|
$stream = new BinaryStream($str);
|
||||||
|
|
||||||
|
while($stream->offset < $len){
|
||||||
|
$buf = $stream->getString();
|
||||||
|
|
||||||
|
if(($pk = $this->getPacket(ord($buf{0}))) !== null){
|
||||||
if($pk::NETWORK_ID === Info::BATCH_PACKET){
|
if($pk::NETWORK_ID === Info::BATCH_PACKET){
|
||||||
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
|
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
|
||||||
}
|
}
|
||||||
@ -228,10 +231,6 @@ class Network{
|
|||||||
|
|
||||||
$pk->decode();
|
$pk->decode();
|
||||||
$p->handleDataPacket($pk);
|
$p->handleDataPacket($pk);
|
||||||
|
|
||||||
if($pk->getOffset() <= 0){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch(\Throwable $e){
|
}catch(\Throwable $e){
|
||||||
|
@ -30,14 +30,12 @@ class BatchPacket extends DataPacket{
|
|||||||
public $payload;
|
public $payload;
|
||||||
|
|
||||||
public function decode(){
|
public function decode(){
|
||||||
$size = $this->getInt();
|
$this->payload = $this->getString();
|
||||||
$this->payload = $this->get($size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function encode(){
|
public function encode(){
|
||||||
$this->reset();
|
$this->reset();
|
||||||
$this->putInt(strlen($this->payload));
|
$this->putString($this->payload);
|
||||||
$this->put($this->payload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ interface Info{
|
|||||||
/**
|
/**
|
||||||
* Actual Minecraft: PE protocol version
|
* Actual Minecraft: PE protocol version
|
||||||
*/
|
*/
|
||||||
const CURRENT_PROTOCOL = 84;
|
const CURRENT_PROTOCOL = 90;
|
||||||
|
|
||||||
const LOGIN_PACKET = 0x01;
|
const LOGIN_PACKET = 0x01;
|
||||||
const PLAY_STATUS_PACKET = 0x02;
|
const PLAY_STATUS_PACKET = 0x02;
|
||||||
@ -45,57 +45,66 @@ interface Info{
|
|||||||
const ADD_ENTITY_PACKET = 0x0b;
|
const ADD_ENTITY_PACKET = 0x0b;
|
||||||
const REMOVE_ENTITY_PACKET = 0x0c;
|
const REMOVE_ENTITY_PACKET = 0x0c;
|
||||||
const ADD_ITEM_ENTITY_PACKET = 0x0d;
|
const ADD_ITEM_ENTITY_PACKET = 0x0d;
|
||||||
const TAKE_ITEM_ENTITY_PACKET = 0x0e;
|
const ADD_HANGING_ENTITY_PACKET = 0x0e;
|
||||||
const MOVE_ENTITY_PACKET = 0x0f;
|
const TAKE_ITEM_ENTITY_PACKET = 0x0f;
|
||||||
const MOVE_PLAYER_PACKET = 0x10;
|
const MOVE_ENTITY_PACKET = 0x10;
|
||||||
const RIDER_JUMP_PACKET = 0x11;
|
const MOVE_PLAYER_PACKET = 0x11;
|
||||||
const REMOVE_BLOCK_PACKET = 0x12;
|
const RIDER_JUMP_PACKET = 0x12;
|
||||||
const UPDATE_BLOCK_PACKET = 0x13;
|
const REMOVE_BLOCK_PACKET = 0x13;
|
||||||
const ADD_PAINTING_PACKET = 0x14;
|
const UPDATE_BLOCK_PACKET = 0x14;
|
||||||
const EXPLODE_PACKET = 0x15;
|
const ADD_PAINTING_PACKET = 0x15;
|
||||||
const LEVEL_EVENT_PACKET = 0x16;
|
const EXPLODE_PACKET = 0x16;
|
||||||
const BLOCK_EVENT_PACKET = 0x17;
|
const LEVEL_SOUND_EVENT_PACKET = 0x17;
|
||||||
const ENTITY_EVENT_PACKET = 0x18;
|
const LEVEL_EVENT_PACKET = 0x18;
|
||||||
const MOB_EFFECT_PACKET = 0x19;
|
const BLOCK_EVENT_PACKET = 0x19;
|
||||||
const UPDATE_ATTRIBUTES_PACKET = 0x1a;
|
const ENTITY_EVENT_PACKET = 0x1a;
|
||||||
const MOB_EQUIPMENT_PACKET = 0x1b;
|
const MOB_EFFECT_PACKET = 0x1b;
|
||||||
const MOB_ARMOR_EQUIPMENT_PACKET = 0x1c;
|
const UPDATE_ATTRIBUTES_PACKET = 0x1c;
|
||||||
const INTERACT_PACKET = 0x1e;
|
const MOB_EQUIPMENT_PACKET = 0x1d;
|
||||||
const USE_ITEM_PACKET = 0x1f;
|
const MOB_ARMOR_EQUIPMENT_PACKET = 0x1e;
|
||||||
const PLAYER_ACTION_PACKET = 0x20;
|
const INTERACT_PACKET = 0x1f;
|
||||||
const HURT_ARMOR_PACKET = 0x21;
|
const USE_ITEM_PACKET = 0x20;
|
||||||
const SET_ENTITY_DATA_PACKET = 0x22;
|
const PLAYER_ACTION_PACKET = 0x21;
|
||||||
const SET_ENTITY_MOTION_PACKET = 0x23;
|
const HURT_ARMOR_PACKET = 0x22;
|
||||||
const SET_ENTITY_LINK_PACKET = 0x24;
|
const SET_ENTITY_DATA_PACKET = 0x23;
|
||||||
const SET_HEALTH_PACKET = 0x25;
|
const SET_ENTITY_MOTION_PACKET = 0x24;
|
||||||
const SET_SPAWN_POSITION_PACKET = 0x26;
|
const SET_ENTITY_LINK_PACKET = 0x25;
|
||||||
const ANIMATE_PACKET = 0x27;
|
const SET_HEALTH_PACKET = 0x26;
|
||||||
const RESPAWN_PACKET = 0x28;
|
const SET_SPAWN_POSITION_PACKET = 0x27;
|
||||||
const DROP_ITEM_PACKET = 0x29;
|
const ANIMATE_PACKET = 0x28;
|
||||||
const CONTAINER_OPEN_PACKET = 0x2a;
|
const RESPAWN_PACKET = 0x29;
|
||||||
const CONTAINER_CLOSE_PACKET = 0x2b;
|
const DROP_ITEM_PACKET = 0x2a;
|
||||||
const CONTAINER_SET_SLOT_PACKET = 0x2c;
|
const INVENTORY_ACTION_PACKET = 0x2b;
|
||||||
const CONTAINER_SET_DATA_PACKET = 0x2d;
|
const CONTAINER_OPEN_PACKET = 0x2c;
|
||||||
const CONTAINER_SET_CONTENT_PACKET = 0x2e;
|
const CONTAINER_CLOSE_PACKET = 0x2d;
|
||||||
const CRAFTING_DATA_PACKET = 0x2f;
|
const CONTAINER_SET_SLOT_PACKET = 0x2e;
|
||||||
const CRAFTING_EVENT_PACKET = 0x30;
|
const CONTAINER_SET_DATA_PACKET = 0x2f;
|
||||||
const ADVENTURE_SETTINGS_PACKET = 0x31;
|
const CONTAINER_SET_CONTENT_PACKET = 0x30;
|
||||||
const BLOCK_ENTITY_DATA_PACKET = 0x32;
|
const CRAFTING_DATA_PACKET = 0x31;
|
||||||
const PLAYER_INPUT_PACKET = 0x33;
|
const CRAFTING_EVENT_PACKET = 0x32;
|
||||||
const FULL_CHUNK_DATA_PACKET = 0x34;
|
const ADVENTURE_SETTINGS_PACKET = 0x33;
|
||||||
const SET_DIFFICULTY_PACKET = 0x35;
|
const BLOCK_ENTITY_DATA_PACKET = 0x34;
|
||||||
const CHANGE_DIMENSION_PACKET = 0x36;
|
const PLAYER_INPUT_PACKET = 0x35;
|
||||||
const SET_PLAYER_GAMETYPE_PACKET = 0x37;
|
const FULL_CHUNK_DATA_PACKET = 0x36;
|
||||||
const PLAYER_LIST_PACKET = 0x38;
|
const SET_COMMANDS_ENABLED_PACKET = 0x37;
|
||||||
const TELEMETRY_EVENT_PACKET = 0x39;
|
const SET_DIFFICULTY_PACKET = 0x38;
|
||||||
const SPAWN_EXPERIENCE_ORB_PACKET = 0x3a;
|
const CHANGE_DIMENSION_PACKET = 0x39;
|
||||||
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x3b;
|
const SET_PLAYER_GAMETYPE_PACKET = 0x3a;
|
||||||
const MAP_INFO_REQUEST_PACKET = 0x3c;
|
const PLAYER_LIST_PACKET = 0x3b;
|
||||||
const REQUEST_CHUNK_RADIUS_PACKET = 0x3d;
|
const TELEMETRY_EVENT_PACKET = 0x3c;
|
||||||
const CHUNK_RADIUS_UPDATED_PACKET = 0x3e;
|
const SPAWN_EXPERIENCE_ORB_PACKET = 0x3d;
|
||||||
const ITEM_FRAME_DROP_ITEM_PACKET = 0x3f;
|
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x3e;
|
||||||
const REPLACE_SELECTED_ITEM_PACKET = 0x40;
|
const MAP_INFO_REQUEST_PACKET = 0x3f;
|
||||||
const ADD_ITEM_PACKET = 0x41;
|
const REQUEST_CHUNK_RADIUS_PACKET = 0x40;
|
||||||
|
const CHUNK_RADIUS_UPDATED_PACKET = 0x41;
|
||||||
|
const ITEM_FRAME_DROP_ITEM_PACKET = 0x42;
|
||||||
|
const REPLACE_SELECTED_ITEM_PACKET = 0x43;
|
||||||
|
const GAME_RULES_CHANGED_PACKET = 0x44;
|
||||||
|
const CAMERA_PACKET = 0x45;
|
||||||
|
const ADD_ITEM_PACKET = 0x46;
|
||||||
|
const BOSS_EVENT_PACKET = 0x47;
|
||||||
|
const AVAILABLE_COMMANDS_PACKET = 0x48;
|
||||||
|
const COMMAND_STEP_PACKET = 0x49;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,9 +27,11 @@ namespace pocketmine\network\protocol;
|
|||||||
class LoginPacket extends DataPacket{
|
class LoginPacket extends DataPacket{
|
||||||
const NETWORK_ID = Info::LOGIN_PACKET;
|
const NETWORK_ID = Info::LOGIN_PACKET;
|
||||||
|
|
||||||
|
const EDITION_POCKET = 0;
|
||||||
|
|
||||||
public $username;
|
public $username;
|
||||||
public $protocol;
|
public $protocol;
|
||||||
|
public $gameEdition;
|
||||||
public $clientUUID;
|
public $clientUUID;
|
||||||
public $clientId;
|
public $clientId;
|
||||||
public $identityPublicKey;
|
public $identityPublicKey;
|
||||||
@ -44,7 +46,10 @@ class LoginPacket extends DataPacket{
|
|||||||
if($this->protocol !== Info::CURRENT_PROTOCOL){
|
if($this->protocol !== Info::CURRENT_PROTOCOL){
|
||||||
return; //Do not attempt to decode for non-accepted protocols
|
return; //Do not attempt to decode for non-accepted protocols
|
||||||
}
|
}
|
||||||
$str = zlib_decode($this->get($this->getInt()), 1024 * 1024 * 64);
|
|
||||||
|
$this->gameEdition = $this->getByte();
|
||||||
|
|
||||||
|
$str = zlib_decode($this->getString(), 1024 * 1024 * 64);
|
||||||
|
|
||||||
$this->setBuffer($str, 0);
|
$this->setBuffer($str, 0);
|
||||||
|
|
||||||
|
@ -27,18 +27,27 @@ namespace pocketmine\network\protocol;
|
|||||||
class StartGamePacket extends DataPacket{
|
class StartGamePacket extends DataPacket{
|
||||||
const NETWORK_ID = Info::START_GAME_PACKET;
|
const NETWORK_ID = Info::START_GAME_PACKET;
|
||||||
|
|
||||||
public $seed;
|
public $entityUniqueId;
|
||||||
public $dimension;
|
public $entityRuntimeId;
|
||||||
public $generator;
|
|
||||||
public $gamemode;
|
|
||||||
public $eid;
|
|
||||||
public $spawnX;
|
|
||||||
public $spawnY;
|
|
||||||
public $spawnZ;
|
|
||||||
public $x;
|
public $x;
|
||||||
public $y;
|
public $y;
|
||||||
public $z;
|
public $z;
|
||||||
|
public $seed;
|
||||||
|
public $dimension;
|
||||||
|
public $generator = 1; //default infinite - 0 old, 1 infinite, 2 flat
|
||||||
|
public $gamemode;
|
||||||
|
public $difficulty;
|
||||||
|
public $spawnX;
|
||||||
|
public $spawnY;
|
||||||
|
public $spawnZ;
|
||||||
|
public $hasBeenLoadedInCreative = 1;
|
||||||
|
public $dayCycleStopTime = -1; //-1 = not stopped, any positive value = stopped at that time
|
||||||
|
public $eduMode = 0;
|
||||||
|
public $rainLevel;
|
||||||
|
public $lightningLevel;
|
||||||
|
public $commandsEnabled;
|
||||||
public $unknown;
|
public $unknown;
|
||||||
|
public $worldName;
|
||||||
|
|
||||||
public function decode(){
|
public function decode(){
|
||||||
|
|
||||||
@ -46,21 +55,25 @@ class StartGamePacket extends DataPacket{
|
|||||||
|
|
||||||
public function encode(){
|
public function encode(){
|
||||||
$this->reset();
|
$this->reset();
|
||||||
$this->putInt($this->seed);
|
$this->putEntityId($this->entityUniqueId); //EntityUniqueID
|
||||||
$this->putByte($this->dimension);
|
$this->putEntityId($this->entityRuntimeId); //EntityRuntimeID
|
||||||
$this->putInt($this->generator);
|
$this->putVector3f($this->x, $this->y, $this->z);
|
||||||
$this->putInt($this->gamemode);
|
$this->putLFloat(0); //TODO: find out what these are (yaw/pitch?)
|
||||||
$this->putLong($this->eid);
|
$this->putLFloat(0);
|
||||||
$this->putInt($this->spawnX);
|
$this->putVarInt($this->seed);
|
||||||
$this->putInt($this->spawnY);
|
$this->putVarInt($this->dimension);
|
||||||
$this->putInt($this->spawnZ);
|
$this->putVarInt($this->generator);
|
||||||
$this->putFloat($this->x);
|
$this->putVarInt($this->gamemode);
|
||||||
$this->putFloat($this->y);
|
$this->putVarInt($this->difficulty);
|
||||||
$this->putFloat($this->z);
|
$this->putBlockCoords($this->spawnX, $this->spawnY, $this->spawnZ);
|
||||||
$this->putByte(1);
|
$this->putByte($this->hasBeenLoadedInCreative);
|
||||||
$this->putByte(1);
|
$this->putVarInt($this->dayCycleStopTime);
|
||||||
$this->putByte(0);
|
$this->putByte($this->eduMode);
|
||||||
|
$this->putLFloat($this->rainLevel);
|
||||||
|
$this->putLFloat($this->lightningLevel);
|
||||||
|
$this->putByte($this->commandsEnabled);
|
||||||
$this->putString($this->unknown);
|
$this->putString($this->unknown);
|
||||||
|
$this->putString($this->worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -428,8 +428,45 @@ class Binary{
|
|||||||
return self::readLong(strrev($str));
|
return self::readLong(strrev($str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: varlong, length checks
|
||||||
|
|
||||||
public static function writeLLong($value){
|
public static function writeLLong($value){
|
||||||
return strrev(self::writeLong($value));
|
return strrev(self::writeLong($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function readVarInt($stream){
|
||||||
|
$raw = self::readUnsignedVarInt($stream);
|
||||||
|
$temp = ((($raw << 31) >> 31) ^ $raw) >> 1;
|
||||||
|
return $temp ^ ($raw & (1 << 31));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function readUnsignedVarInt($stream){
|
||||||
|
$value = 0;
|
||||||
|
$i = 0;
|
||||||
|
do{
|
||||||
|
$value |= ((($b = $stream->getByte()) & 0x7f) << $i);
|
||||||
|
$i += 7;
|
||||||
|
}while($b & 0x80);
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeVarInt($v){
|
||||||
|
return self::writeUnsignedVarInt(($v << 1) ^ ($v >> 31));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeUnsignedVarInt($v){
|
||||||
|
$buf = "";
|
||||||
|
do{
|
||||||
|
$w = $v & 0x7f;
|
||||||
|
if(($v >> 7) !== 0){
|
||||||
|
$w = $v | 0x80;
|
||||||
|
}
|
||||||
|
$buf .= self::writeByte($w);
|
||||||
|
$v >>= 7;
|
||||||
|
}while($v);
|
||||||
|
|
||||||
|
return $buf;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -233,14 +233,76 @@ class BinaryStream extends \stdClass{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getString(){
|
public function getString(){
|
||||||
return $this->get($this->getShort());
|
return $this->get($this->getUnsignedVarInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function putString($v){
|
public function putString($v){
|
||||||
$this->putShort(strlen($v));
|
$this->putUnsignedVarInt(strlen($v));
|
||||||
$this->put($v);
|
$this->put($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: varint64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads an unsigned varint32 from the stream.
|
||||||
|
*/
|
||||||
|
public function getUnsignedVarInt(){
|
||||||
|
return Binary::readUnsignedVarInt($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an unsigned varint32 to the stream.
|
||||||
|
*/
|
||||||
|
public function putUnsignedVarInt($v){
|
||||||
|
$this->put(Binary::writeUnsignedVarInt($v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a signed varint32 from the stream.
|
||||||
|
*/
|
||||||
|
public function getVarInt(){
|
||||||
|
return Binary::readVarInt($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a signed varint32 to the stream.
|
||||||
|
*/
|
||||||
|
public function putVarInt($v){
|
||||||
|
$this->put(Binary::writeVarInt($v));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEntityId(){
|
||||||
|
return $this->getVarInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function putEntityId($v){
|
||||||
|
$this->putVarInt($v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlockCoords(&$x, &$y, &$z){
|
||||||
|
$x = $this->getVarInt();
|
||||||
|
$y = $this->getByte();
|
||||||
|
$z = $this->getVarInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function putBlockCoords(int $x, int $y, int $z){
|
||||||
|
$this->putVarInt($x);
|
||||||
|
$this->putByte($y);
|
||||||
|
$this->putVarInt($z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVector3f(&$x, &$y, &$z){
|
||||||
|
$x = $this->getLFloat();
|
||||||
|
$y = $this->getLFloat();
|
||||||
|
$z = $this->getLFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function putVector3f(float $x, float $y, float $z){
|
||||||
|
$this->putLFloat($x);
|
||||||
|
$this->putLFloat($y);
|
||||||
|
$this->putLFloat($z);
|
||||||
|
}
|
||||||
|
|
||||||
public function feof(){
|
public function feof(){
|
||||||
return !isset($this->buffer{$this->offset});
|
return !isset($this->buffer{$this->offset});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user