mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-23 00:55:57 +00:00
Merge pull request #42 from pmmp/0.16
Update to 0.16 (1.6.1dev, API 2.1.0)
This commit is contained in:
commit
dc07fc42b4
@ -23,6 +23,7 @@ namespace pocketmine;
|
||||
|
||||
use pocketmine\block\Air;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\Effect;
|
||||
@ -60,6 +61,7 @@ use pocketmine\event\player\PlayerMoveEvent;
|
||||
use pocketmine\event\player\PlayerPreLoginEvent;
|
||||
use pocketmine\event\player\PlayerQuitEvent;
|
||||
use pocketmine\event\player\PlayerRespawnEvent;
|
||||
use pocketmine\event\player\PlayerToggleFlightEvent;
|
||||
use pocketmine\event\player\PlayerToggleSneakEvent;
|
||||
use pocketmine\event\player\PlayerToggleSprintEvent;
|
||||
use pocketmine\event\server\DataPacketReceiveEvent;
|
||||
@ -100,6 +102,7 @@ use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\protocol\AnimatePacket;
|
||||
use pocketmine\network\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\protocol\BatchPacket;
|
||||
use pocketmine\network\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\protocol\ContainerClosePacket;
|
||||
@ -113,6 +116,7 @@ use pocketmine\network\protocol\InteractPacket;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\protocol\ResourcePacksInfoPacket;
|
||||
use pocketmine\network\protocol\RespawnPacket;
|
||||
use pocketmine\network\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
@ -132,9 +136,9 @@ use pocketmine\plugin\Plugin;
|
||||
use pocketmine\tile\Sign;
|
||||
use pocketmine\tile\Spawnable;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\UUID;
|
||||
use raklib\Binary;
|
||||
|
||||
|
||||
/**
|
||||
@ -230,9 +234,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
protected $inAirTicks = 0;
|
||||
protected $startAirTicks = 5;
|
||||
|
||||
//TODO: Abilities
|
||||
protected $autoJump = true;
|
||||
|
||||
protected $allowFlight = false;
|
||||
protected $flying = false;
|
||||
|
||||
private $needACK = [];
|
||||
|
||||
@ -309,10 +314,19 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->sendSettings();
|
||||
}
|
||||
|
||||
public function getAllowFlight(){
|
||||
public function getAllowFlight() : bool{
|
||||
return $this->allowFlight;
|
||||
}
|
||||
|
||||
public function setFlying(bool $value){
|
||||
$this->flying = $value;
|
||||
$this->sendSettings();
|
||||
}
|
||||
|
||||
public function isFlying() : bool{
|
||||
return $this->flying;
|
||||
}
|
||||
|
||||
public function setAutoJump($value){
|
||||
$this->autoJump = $value;
|
||||
$this->sendSettings();
|
||||
@ -426,6 +440,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
|
||||
$this->recalculatePermissions();
|
||||
$this->sendSettings();
|
||||
$this->sendCommandData();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,6 +505,25 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
return $this->perm->getEffectivePermissions();
|
||||
}
|
||||
|
||||
public function sendCommandData(){
|
||||
$pk = new AvailableCommandsPacket();
|
||||
$data = new \stdClass();
|
||||
$count = 0;
|
||||
foreach($this->server->getCommandMap()->getCommands() as $command){
|
||||
if(!$command->testPermissionSilent($this)){
|
||||
continue;
|
||||
}
|
||||
++$count;
|
||||
$data->{$command->getName()}->versions[0] = $command->generateCustomCommandData($this);
|
||||
}
|
||||
|
||||
if($count > 0){
|
||||
//TODO: structure checking
|
||||
$pk->commands = json_encode($data);
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SourceInterface $interface
|
||||
* @param null $clientID
|
||||
@ -982,7 +1017,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->sleeping = clone $pos;
|
||||
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [$pos->x, $pos->y, $pos->z]);
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, true);
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, true, self::DATA_TYPE_BYTE);
|
||||
|
||||
$this->setSpawn($pos);
|
||||
|
||||
@ -1017,7 +1052,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
$this->sleeping = null;
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]);
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false, self::DATA_TYPE_BYTE);
|
||||
|
||||
$this->level->sleepTicks = 0;
|
||||
|
||||
@ -1064,36 +1099,56 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
/**
|
||||
* Sets the gamemode, and if needed, kicks the Player.
|
||||
*
|
||||
* @param int $gm
|
||||
* @param int $gm
|
||||
* @param bool $client if the client made this change in their GUI
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setGamemode($gm){
|
||||
public function setGamemode(int $gm, bool $client = false){
|
||||
if($gm < 0 or $gm > 3 or $this->gamemode === $gm){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm));
|
||||
if($ev->isCancelled()){
|
||||
if($client){ //gamemode change by client in the GUI
|
||||
$pk = new SetPlayerGameTypePacket();
|
||||
$pk->gamemode = $this->gamemode & 0x01;
|
||||
$this->dataPacket($pk);
|
||||
$this->sendSettings();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->gamemode = $gm;
|
||||
|
||||
$this->allowFlight = $this->isCreative();
|
||||
|
||||
if($this->isSpectator()){
|
||||
$this->flying = true;
|
||||
$this->despawnFromAll();
|
||||
|
||||
// Client automatically turns off flight controls when on the ground.
|
||||
// A combination of this hack and a new AdventureSettings flag FINALLY
|
||||
// fixes spectator flight controls. Thank @robske110 for this hack.
|
||||
$this->teleport($this->temporalVector->setComponents($this->x, $this->y + 0.1, $this->z));
|
||||
}else{
|
||||
if($this->isSurvival()){
|
||||
$this->flying = false;
|
||||
}
|
||||
$this->spawnToAll();
|
||||
}
|
||||
|
||||
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
|
||||
$this->resetFallDistance();
|
||||
|
||||
$pk = new SetPlayerGameTypePacket();
|
||||
$pk->gamemode = $this->gamemode & 0x01;
|
||||
$this->dataPacket($pk);
|
||||
$this->sendSettings();
|
||||
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
|
||||
if(!$client){ //Gamemode changed by server, do not send for client changes
|
||||
$pk = new SetPlayerGameTypePacket();
|
||||
$pk->gamemode = $this->gamemode & 0x01;
|
||||
$this->dataPacket($pk);
|
||||
$this->sendSettings();
|
||||
}else{
|
||||
Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)]));
|
||||
}
|
||||
|
||||
$this->inventory->sendContents($this);
|
||||
$this->inventory->sendContents($this->getViewers());
|
||||
@ -1109,66 +1164,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
* Sends all the option flags
|
||||
*/
|
||||
public function sendSettings(){
|
||||
/*
|
||||
bit mask | flag name
|
||||
0x00000001 world_inmutable
|
||||
0x00000002 no_pvp
|
||||
0x00000004 no_pvm
|
||||
0x00000008 no_mvp
|
||||
0x00000010 static_time
|
||||
0x00000020 nametags_visible
|
||||
0x00000040 auto_jump
|
||||
0x00000080 allow_fly
|
||||
0x00000100 noclip
|
||||
0x00000200 ?
|
||||
0x00000400 ?
|
||||
0x00000800 ?
|
||||
0x00001000 ?
|
||||
0x00002000 ?
|
||||
0x00004000 ?
|
||||
0x00008000 ?
|
||||
0x00010000 ?
|
||||
0x00020000 ?
|
||||
0x00040000 ?
|
||||
0x00080000 ?
|
||||
0x00100000 ?
|
||||
0x00200000 ?
|
||||
0x00400000 ?
|
||||
0x00800000 ?
|
||||
0x01000000 ?
|
||||
0x02000000 ?
|
||||
0x04000000 ?
|
||||
0x08000000 ?
|
||||
0x10000000 ?
|
||||
0x20000000 ?
|
||||
0x40000000 ?
|
||||
0x80000000 ?
|
||||
*/
|
||||
$flags = 0;
|
||||
if($this->isAdventure()){
|
||||
$flags |= 0x01; //Do not allow placing/breaking blocks, adventure mode
|
||||
}
|
||||
|
||||
/*if($nametags !== false){
|
||||
$flags |= 0x20; //Show Nametags
|
||||
}*/
|
||||
|
||||
if($this->autoJump){
|
||||
$flags |= 0x40;
|
||||
}
|
||||
|
||||
if($this->allowFlight){
|
||||
$flags |= 0x80;
|
||||
}
|
||||
|
||||
if($this->isSpectator()){
|
||||
$flags |= 0x100;
|
||||
}
|
||||
|
||||
$pk = new AdventureSettingsPacket();
|
||||
$pk->flags = $flags;
|
||||
$pk->userPermission = 2;
|
||||
$pk->globalPermission = 2;
|
||||
$pk->flags = 0;
|
||||
$pk->worldImmutable = $this->isAdventure();
|
||||
$pk->autoJump = $this->autoJump;
|
||||
$pk->allowFlight = $this->allowFlight;
|
||||
$pk->noClip = $this->isSpectator();
|
||||
$pk->isFlying = $this->flying;
|
||||
$pk->userPermission = ($this->isOp() ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL);
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
|
||||
@ -1205,31 +1208,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
return [];
|
||||
}
|
||||
|
||||
public function setDataProperty($id, $type, $value, $send = true){
|
||||
if(parent::setDataProperty($id, $type, $value, $send)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function entityBaseTick($tickDiff = 1){
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
$entries = $this->attributeMap->needSend();
|
||||
if(count($entries) > 0){
|
||||
$pk = new UpdateAttributesPacket();
|
||||
$pk->entityId = 0;
|
||||
$pk->entries = $entries;
|
||||
$this->dataPacket($pk);
|
||||
foreach($entries as $entry){
|
||||
$entry->markSynchronized();
|
||||
}
|
||||
}
|
||||
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
protected function checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz){
|
||||
if(!$this->onGround or $movY != 0){
|
||||
$bb = clone $this->boundingBox;
|
||||
@ -1451,7 +1429,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
if($this->chunk !== null){
|
||||
$this->level->addEntityMotion($this->chunk->getX(), $this->chunk->getZ(), $this->getId(), $this->motionX, $this->motionY, $this->motionZ);
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->entities[] = [0, $mot->x, $mot->y, $mot->z];
|
||||
$pk->eid = 0;
|
||||
$pk->motionX = $mot->x;
|
||||
$pk->motionY = $mot->y;
|
||||
$pk->motionZ = $mot->z;
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
|
||||
@ -1465,6 +1446,20 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
|
||||
protected function updateMovement(){
|
||||
|
||||
}
|
||||
|
||||
public function sendAttributes(bool $sendAll = false){
|
||||
$entries = $sendAll ? $this->attributeMap->getAll() : $this->attributeMap->needSend();
|
||||
if(count($entries) > 0){
|
||||
$pk = new UpdateAttributesPacket();
|
||||
$pk->entityId = 0;
|
||||
$pk->entries = $entries;
|
||||
$this->dataPacket($pk);
|
||||
foreach($entries as $entry){
|
||||
$entry->markSynchronized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onUpdate($currentTick){
|
||||
@ -1482,6 +1477,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$this->sendAttributes();
|
||||
|
||||
if(!$this->isAlive() and $this->spawned){
|
||||
++$this->deadTicks;
|
||||
if($this->deadTicks >= 10){
|
||||
@ -1505,7 +1502,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
$this->inAirTicks = 0;
|
||||
}else{
|
||||
if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){
|
||||
if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and !$this->isImmobile()){
|
||||
$expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks));
|
||||
$diff = ($this->speed->y - $expectedVelocity) ** 2;
|
||||
|
||||
@ -1678,9 +1675,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->inventory->setHeldItemSlot($this->inventory->getHotbarSlotIndex(0));
|
||||
}
|
||||
|
||||
$pk = new PlayStatusPacket();
|
||||
$pk->status = PlayStatusPacket::LOGIN_SUCCESS;
|
||||
$this->dataPacket($pk);
|
||||
$this->dataPacket(new ResourcePacksInfoPacket());
|
||||
|
||||
if($this->spawnPosition === null and isset($this->namedtag->SpawnLevel) and ($level = $this->server->getLevelByName($this->namedtag["SpawnLevel"])) instanceof Level){
|
||||
$this->spawnPosition = new Position($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level);
|
||||
@ -1689,17 +1684,26 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$spawnPosition = $this->getSpawn();
|
||||
|
||||
$pk = new StartGamePacket();
|
||||
$pk->seed = -1;
|
||||
$pk->dimension = 0;
|
||||
$pk->entityUniqueId = 0;
|
||||
$pk->entityRuntimeId = 0;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->spawnX = (int) $spawnPosition->x;
|
||||
$pk->spawnY = (int) $spawnPosition->y;
|
||||
$pk->spawnZ = (int) $spawnPosition->z;
|
||||
$pk->generator = 1; //0 old, 1 infinite, 2 flat
|
||||
$pk->seed = -1;
|
||||
$pk->dimension = 0; //TODO: implement this properly
|
||||
$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 = 1;
|
||||
$pk->levelId = "";
|
||||
$pk->worldName = $this->server->getMotd();
|
||||
$this->dataPacket($pk);
|
||||
|
||||
$pk = new SetTimePacket();
|
||||
@ -1707,19 +1711,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$pk->started = $this->level->stopTime == false;
|
||||
$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->health = $this->getHealth();
|
||||
$this->dataPacket($pk);
|
||||
|
||||
$pk = new SetDifficultyPacket();
|
||||
$pk->difficulty = $this->server->getDifficulty();
|
||||
$this->dataPacket($pk);
|
||||
$this->sendAttributes(true);
|
||||
$this->setNameTagVisible(true);
|
||||
$this->setNameTagAlwaysVisible(true);
|
||||
|
||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
|
||||
TextFormat::AQUA . $this->username . TextFormat::WHITE,
|
||||
@ -1736,6 +1730,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->setRemoveFormat(false);
|
||||
}
|
||||
|
||||
$this->sendCommandData();
|
||||
|
||||
if($this->isCreative()){
|
||||
$this->inventory->sendCreativeContents();
|
||||
}
|
||||
@ -1880,6 +1876,21 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
$this->forceMovement = null;
|
||||
|
||||
break;
|
||||
case ProtocolInfo::ADVENTURE_SETTINGS_PACKET:
|
||||
//TODO: player abilities, check for other changes
|
||||
if($packet->isFlying and !$this->allowFlight){
|
||||
$this->kick("Flying is not enabled on this server");
|
||||
break;
|
||||
}else{
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerToggleFlightEvent($this, $packet->isFlying));
|
||||
if($ev->isCancelled()){
|
||||
$this->sendSettings();
|
||||
}else{
|
||||
$this->flying = $ev->isFlying();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ProtocolInfo::MOB_EQUIPMENT_PACKET:
|
||||
if($this->spawned === false or !$this->isAlive()){
|
||||
@ -1989,8 +2000,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
$this->level->sendBlocks([$this], [$target, $block], UpdateBlockPacket::FLAG_ALL_PRIORITY);
|
||||
break;
|
||||
}elseif($packet->face === 0xff){
|
||||
$aimPos = (new Vector3($packet->x / 32768, $packet->y / 32768, $packet->z / 32768))->normalize();
|
||||
}elseif($packet->face === -1){
|
||||
$aimPos = new Vector3(
|
||||
-sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI),
|
||||
-sin($this->pitch / 180 * M_PI),
|
||||
cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)
|
||||
);
|
||||
|
||||
if($this->isCreative()){
|
||||
$item = $this->inventory->getItemInHand();
|
||||
@ -2194,7 +2209,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->setSneaking(false);
|
||||
|
||||
$this->extinguish();
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300, false);
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 400, false);
|
||||
$this->deadTicks = 0;
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
@ -2308,123 +2323,120 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$target = $this->level->getEntity($packet->target);
|
||||
|
||||
$cancelled = false;
|
||||
|
||||
if($packet->action === InteractPacket::ACTION_RIGHT_CLICK){
|
||||
// TODO handle
|
||||
break;
|
||||
}
|
||||
|
||||
if(
|
||||
$target instanceof Player and
|
||||
$this->server->getConfigBoolean("pvp", true) === false
|
||||
){
|
||||
$cancelled = true;
|
||||
}
|
||||
|
||||
if($target instanceof Entity and $this->getGamemode() !== Player::VIEW and $this->isAlive() and $target->isAlive()){
|
||||
if($target instanceof DroppedItem or $target instanceof Arrow){
|
||||
$this->kick("Attempting to attack an invalid entity");
|
||||
$this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()]));
|
||||
break;
|
||||
}
|
||||
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$damageTable = [
|
||||
Item::WOODEN_SWORD => 4,
|
||||
Item::GOLD_SWORD => 4,
|
||||
Item::STONE_SWORD => 5,
|
||||
Item::IRON_SWORD => 6,
|
||||
Item::DIAMOND_SWORD => 7,
|
||||
|
||||
Item::WOODEN_AXE => 3,
|
||||
Item::GOLD_AXE => 3,
|
||||
Item::STONE_AXE => 3,
|
||||
Item::IRON_AXE => 5,
|
||||
Item::DIAMOND_AXE => 6,
|
||||
|
||||
Item::WOODEN_PICKAXE => 2,
|
||||
Item::GOLD_PICKAXE => 2,
|
||||
Item::STONE_PICKAXE => 3,
|
||||
Item::IRON_PICKAXE => 4,
|
||||
Item::DIAMOND_PICKAXE => 5,
|
||||
|
||||
Item::WOODEN_SHOVEL => 1,
|
||||
Item::GOLD_SHOVEL => 1,
|
||||
Item::STONE_SHOVEL => 2,
|
||||
Item::IRON_SHOVEL => 3,
|
||||
Item::DIAMOND_SHOVEL => 4,
|
||||
];
|
||||
|
||||
$damage = [
|
||||
EntityDamageEvent::MODIFIER_BASE => isset($damageTable[$item->getId()]) ? $damageTable[$item->getId()] : 1,
|
||||
];
|
||||
|
||||
if(!$this->canInteract($target, 8)){
|
||||
$cancelled = true;
|
||||
}elseif($target instanceof Player){
|
||||
if(($target->getGamemode() & 0x01) > 0){
|
||||
break;
|
||||
}elseif($this->server->getConfigBoolean("pvp") !== true or $this->server->getDifficulty() === 0){
|
||||
switch($packet->action){
|
||||
case InteractPacket::ACTION_LEFT_CLICK: //Attack
|
||||
if($target instanceof Player and $this->server->getConfigBoolean("pvp", true) === false){
|
||||
$cancelled = true;
|
||||
}
|
||||
|
||||
$armorValues = [
|
||||
Item::LEATHER_CAP => 1,
|
||||
Item::LEATHER_TUNIC => 3,
|
||||
Item::LEATHER_PANTS => 2,
|
||||
Item::LEATHER_BOOTS => 1,
|
||||
Item::CHAIN_HELMET => 1,
|
||||
Item::CHAIN_CHESTPLATE => 5,
|
||||
Item::CHAIN_LEGGINGS => 4,
|
||||
Item::CHAIN_BOOTS => 1,
|
||||
Item::GOLD_HELMET => 1,
|
||||
Item::GOLD_CHESTPLATE => 5,
|
||||
Item::GOLD_LEGGINGS => 3,
|
||||
Item::GOLD_BOOTS => 1,
|
||||
Item::IRON_HELMET => 2,
|
||||
Item::IRON_CHESTPLATE => 6,
|
||||
Item::IRON_LEGGINGS => 5,
|
||||
Item::IRON_BOOTS => 2,
|
||||
Item::DIAMOND_HELMET => 3,
|
||||
Item::DIAMOND_CHESTPLATE => 8,
|
||||
Item::DIAMOND_LEGGINGS => 6,
|
||||
Item::DIAMOND_BOOTS => 3,
|
||||
];
|
||||
$points = 0;
|
||||
foreach($target->getInventory()->getArmorContents() as $index => $i){
|
||||
if(isset($armorValues[$i->getId()])){
|
||||
$points += $armorValues[$i->getId()];
|
||||
if($target instanceof Entity and $this->getGamemode() !== Player::VIEW and $this->isAlive() and $target->isAlive()){
|
||||
if($target instanceof DroppedItem or $target instanceof Arrow){
|
||||
$this->kick("Attempting to attack an invalid entity");
|
||||
$this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$damage[EntityDamageEvent::MODIFIER_ARMOR] = -floor($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04);
|
||||
}
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$damageTable = [
|
||||
Item::WOODEN_SWORD => 4,
|
||||
Item::GOLD_SWORD => 4,
|
||||
Item::STONE_SWORD => 5,
|
||||
Item::IRON_SWORD => 6,
|
||||
Item::DIAMOND_SWORD => 7,
|
||||
|
||||
$ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage);
|
||||
if($cancelled){
|
||||
$ev->setCancelled();
|
||||
}
|
||||
Item::WOODEN_AXE => 3,
|
||||
Item::GOLD_AXE => 3,
|
||||
Item::STONE_AXE => 3,
|
||||
Item::IRON_AXE => 5,
|
||||
Item::DIAMOND_AXE => 6,
|
||||
|
||||
$target->attack($ev->getFinalDamage(), $ev);
|
||||
Item::WOODEN_PICKAXE => 2,
|
||||
Item::GOLD_PICKAXE => 2,
|
||||
Item::STONE_PICKAXE => 3,
|
||||
Item::IRON_PICKAXE => 4,
|
||||
Item::DIAMOND_PICKAXE => 5,
|
||||
|
||||
if($ev->isCancelled()){
|
||||
if($item->isTool() and $this->isSurvival()){
|
||||
$this->inventory->sendContents($this);
|
||||
Item::WOODEN_SHOVEL => 1,
|
||||
Item::GOLD_SHOVEL => 1,
|
||||
Item::STONE_SHOVEL => 2,
|
||||
Item::IRON_SHOVEL => 3,
|
||||
Item::DIAMOND_SHOVEL => 4,
|
||||
];
|
||||
|
||||
$damage = [
|
||||
EntityDamageEvent::MODIFIER_BASE => isset($damageTable[$item->getId()]) ? $damageTable[$item->getId()] : 1,
|
||||
];
|
||||
|
||||
if(!$this->canInteract($target, 8)){
|
||||
$cancelled = true;
|
||||
}elseif($target instanceof Player){
|
||||
if(($target->getGamemode() & 0x01) > 0){
|
||||
break;
|
||||
}elseif($this->server->getConfigBoolean("pvp") !== true or $this->server->getDifficulty() === 0){
|
||||
$cancelled = true;
|
||||
}
|
||||
|
||||
$armorValues = [
|
||||
Item::LEATHER_CAP => 1,
|
||||
Item::LEATHER_TUNIC => 3,
|
||||
Item::LEATHER_PANTS => 2,
|
||||
Item::LEATHER_BOOTS => 1,
|
||||
Item::CHAIN_HELMET => 1,
|
||||
Item::CHAIN_CHESTPLATE => 5,
|
||||
Item::CHAIN_LEGGINGS => 4,
|
||||
Item::CHAIN_BOOTS => 1,
|
||||
Item::GOLD_HELMET => 1,
|
||||
Item::GOLD_CHESTPLATE => 5,
|
||||
Item::GOLD_LEGGINGS => 3,
|
||||
Item::GOLD_BOOTS => 1,
|
||||
Item::IRON_HELMET => 2,
|
||||
Item::IRON_CHESTPLATE => 6,
|
||||
Item::IRON_LEGGINGS => 5,
|
||||
Item::IRON_BOOTS => 2,
|
||||
Item::DIAMOND_HELMET => 3,
|
||||
Item::DIAMOND_CHESTPLATE => 8,
|
||||
Item::DIAMOND_LEGGINGS => 6,
|
||||
Item::DIAMOND_BOOTS => 3,
|
||||
];
|
||||
$points = 0;
|
||||
foreach($target->getInventory()->getArmorContents() as $index => $i){
|
||||
if(isset($armorValues[$i->getId()])){
|
||||
$points += $armorValues[$i->getId()];
|
||||
}
|
||||
}
|
||||
|
||||
$damage[EntityDamageEvent::MODIFIER_ARMOR] = -floor($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04);
|
||||
}
|
||||
|
||||
$ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage);
|
||||
if($cancelled){
|
||||
$ev->setCancelled();
|
||||
}
|
||||
|
||||
$target->attack($ev->getFinalDamage(), $ev);
|
||||
|
||||
if($ev->isCancelled()){
|
||||
if($item->isTool() and $this->isSurvival()){
|
||||
$this->inventory->sendContents($this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->isSurvival()){
|
||||
if($item->isTool()){
|
||||
if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){
|
||||
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1));
|
||||
}else{
|
||||
$this->inventory->setItemInHand($item);
|
||||
}
|
||||
}
|
||||
|
||||
$this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->isSurvival()){
|
||||
if($item->isTool()){
|
||||
if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){
|
||||
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1));
|
||||
}else{
|
||||
$this->inventory->setItemInHand($item);
|
||||
}
|
||||
}
|
||||
|
||||
$this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK);
|
||||
}
|
||||
default:
|
||||
break; //TODO: handle other actions
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2491,6 +2503,26 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false);
|
||||
break;
|
||||
case ProtocolInfo::COMMAND_STEP_PACKET:
|
||||
if($this->spawned === false or !$this->isAlive()){
|
||||
break;
|
||||
}
|
||||
$this->craftingType = 0;
|
||||
$commandText = $packet->command;
|
||||
if($packet->args !== null){
|
||||
foreach($packet->args as $arg){ //command ordering will be an issue
|
||||
$commandText .= " " . $arg;
|
||||
}
|
||||
}
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerCommandPreprocessEvent($this, "/" . $commandText));
|
||||
if($ev->isCancelled()){
|
||||
break;
|
||||
}
|
||||
|
||||
Timings::$playerCommandTimer->startTiming();
|
||||
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1));
|
||||
Timings::$playerCommandTimer->stopTiming();
|
||||
break;
|
||||
case ProtocolInfo::TEXT_PACKET:
|
||||
if($this->spawned === false or !$this->isAlive()){
|
||||
break;
|
||||
@ -2510,9 +2542,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
if($ev->isCancelled()){
|
||||
break;
|
||||
}
|
||||
if(substr($ev->getMessage(), 0, 1) === "/"){ //Command
|
||||
if(substr($ev->getMessage(), 0, 2) === "./"){ //Command (./ = fast hack for old plugins post 0.16)
|
||||
Timings::$playerCommandTimer->startTiming();
|
||||
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1));
|
||||
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 2));
|
||||
Timings::$playerCommandTimer->stopTiming();
|
||||
}else{
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerChatEvent($this, $ev->getMessage()));
|
||||
@ -2808,7 +2840,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$t = $this->level->getTile($pos);
|
||||
if($t instanceof Sign){
|
||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
||||
$nbt->read($packet->namedtag);
|
||||
$nbt->read($packet->namedtag, false, true);
|
||||
$nbt = $nbt->getData();
|
||||
if($nbt["id"] !== Tile::SIGN){
|
||||
$t->spawnTo($this);
|
||||
@ -2839,6 +2871,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$pk->radius = $packet->radius;
|
||||
$this->dataPacket($pk);
|
||||
break;
|
||||
case ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET:
|
||||
if($packet->gamemode !== $this->gamemode){
|
||||
if(!$this->hasPermission("pocketmine.command.gamemode")){
|
||||
$pk = new SetPlayerGameTypePacket();
|
||||
$pk->gamemode = $this->gamemode & 0x01;
|
||||
$this->dataPacket($pk);
|
||||
$this->sendSettings();
|
||||
break;
|
||||
}
|
||||
$this->setGamemode($packet->gamemode, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3504,7 +3548,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$pk->encode();
|
||||
|
||||
$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->isEncoded = true;
|
||||
|
@ -72,11 +72,11 @@ namespace pocketmine {
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
|
||||
const VERSION = "1.6dev";
|
||||
const API_VERSION = "2.0.0";
|
||||
const VERSION = "1.6.1dev";
|
||||
const API_VERSION = "2.1.0";
|
||||
const CODENAME = "Unleashed";
|
||||
const MINECRAFT_VERSION = "v0.15.10.0 alpha";
|
||||
const MINECRAFT_VERSION_NETWORK = "0.15.10.0";
|
||||
const MINECRAFT_VERSION = "v0.16.0.5 alpha";
|
||||
const MINECRAFT_VERSION_NETWORK = "0.16.0.5";
|
||||
|
||||
/*
|
||||
* Startup code. Do not look at it, it may harm you.
|
||||
|
@ -1567,10 +1567,10 @@ class Server{
|
||||
|
||||
InventoryType::init();
|
||||
Block::init();
|
||||
Enchantment::init();
|
||||
Item::init();
|
||||
Biome::init();
|
||||
Effect::init();
|
||||
Enchantment::init();
|
||||
Attribute::init();
|
||||
$this->craftingManager = new CraftingManager();
|
||||
|
||||
@ -1798,9 +1798,9 @@ class Server{
|
||||
if(!$p->isEncoded){
|
||||
$p->encode();
|
||||
}
|
||||
$str .= Binary::writeInt(strlen($p->buffer)) . $p->buffer;
|
||||
$str .= Binary::writeUnsignedVarInt(strlen($p->buffer)) . $p->buffer;
|
||||
}else{
|
||||
$str .= Binary::writeInt(strlen($p)) . $p;
|
||||
$str .= Binary::writeUnsignedVarInt(strlen($p)) . $p;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,7 +1889,7 @@ class Server{
|
||||
}
|
||||
|
||||
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.notFound"));
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::GOLD . "%commands.generic.notFound"));
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2219,6 +2219,9 @@ class Server{
|
||||
$pk = new PlayerListPacket();
|
||||
$pk->type = PlayerListPacket::TYPE_ADD;
|
||||
foreach($this->playerList as $player){
|
||||
if($p === $player){
|
||||
continue; //fixes duplicates
|
||||
}
|
||||
$pk->entries[] = [$player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkinId(), $player->getSkinData()];
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,18 @@ namespace pocketmine\command;
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\event\TimingsHandler;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
abstract class Command{
|
||||
/** @var \stdClass */
|
||||
private static $defaultDataTemplate = null;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var \stdClass */
|
||||
protected $commandData = null;
|
||||
|
||||
/** @var string */
|
||||
private $nextLabel;
|
||||
@ -75,16 +81,49 @@ abstract class Command{
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
public function __construct($name, $description = "", $usageMessage = null, array $aliases = []){
|
||||
$this->name = $name;
|
||||
$this->nextLabel = $name;
|
||||
$this->label = $name;
|
||||
$this->description = $description;
|
||||
$this->commandData = self::generateDefaultData();
|
||||
$this->name = $this->nextLabel = $this->label = $name;
|
||||
$this->setDescription($description);
|
||||
$this->usageMessage = $usageMessage === null ? "/" . $name : $usageMessage;
|
||||
$this->aliases = $aliases;
|
||||
$this->activeAliases = (array) $aliases;
|
||||
$this->setAliases($aliases);
|
||||
$this->timings = new TimingsHandler("** Command: " . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an \stdClass containing command data
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getDefaultCommandData() : \stdClass{
|
||||
return $this->commandData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates modified command data for the specified player
|
||||
* for AvailableCommandsPacket.
|
||||
*
|
||||
* @param Player $player
|
||||
*
|
||||
* @return \stdClass|null
|
||||
*/
|
||||
public function generateCustomCommandData(Player $player){
|
||||
if(!$this->testPermission($player)){
|
||||
return null;
|
||||
}
|
||||
$customData = clone $this->commandData;
|
||||
$customData->aliases = $this->getAliases();
|
||||
foreach($customData->overloads as &$overload){
|
||||
if(($p = @$overload->pocketminePermission) !== null and !$player->hasPermission($p)){
|
||||
unset($overload);
|
||||
}
|
||||
}
|
||||
return $customData;
|
||||
}
|
||||
|
||||
public function getOverloads(): \stdClass{
|
||||
return $this->commandData->overloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandSender $sender
|
||||
* @param string $commandLabel
|
||||
@ -105,14 +144,19 @@ abstract class Command{
|
||||
* @return string
|
||||
*/
|
||||
public function getPermission(){
|
||||
return $this->permission;
|
||||
return $this->commandData->pocketminePermission ?? null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $permission
|
||||
*/
|
||||
public function setPermission($permission){
|
||||
$this->permission = $permission;
|
||||
if($permission !== null){
|
||||
$this->commandData->pocketminePermission = $permission;
|
||||
}else{
|
||||
unset($this->commandData->pocketminePermission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,7 +172,7 @@ abstract class Command{
|
||||
if($this->permissionMessage === null){
|
||||
$target->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.permission"));
|
||||
}elseif($this->permissionMessage !== ""){
|
||||
$target->sendMessage(str_replace("<permission>", $this->permission, $this->permissionMessage));
|
||||
$target->sendMessage(str_replace("<permission>", $this->getPermission(), $this->permissionMessage));
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -140,11 +184,11 @@ abstract class Command{
|
||||
* @return bool
|
||||
*/
|
||||
public function testPermissionSilent(CommandSender $target){
|
||||
if($this->permission === null or $this->permission === ""){
|
||||
if(($perm = $this->getPermission()) === null or $perm === ""){
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach(explode(";", $this->permission) as $permission){
|
||||
foreach(explode(";", $perm) as $permission){
|
||||
if($target->hasPermission($permission)){
|
||||
return true;
|
||||
}
|
||||
@ -197,7 +241,7 @@ abstract class Command{
|
||||
public function unregister(CommandMap $commandMap){
|
||||
if($this->allowChangesFrom($commandMap)){
|
||||
$this->commandMap = null;
|
||||
$this->activeAliases = $this->aliases;
|
||||
$this->activeAliases = $this->commandData->aliases;
|
||||
$this->label = $this->nextLabel;
|
||||
|
||||
return true;
|
||||
@ -240,7 +284,7 @@ abstract class Command{
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(){
|
||||
return $this->description;
|
||||
return $this->commandData->description;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,7 +298,7 @@ abstract class Command{
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
public function setAliases(array $aliases){
|
||||
$this->aliases = $aliases;
|
||||
$this->commandData->aliases = $aliases;
|
||||
if(!$this->isRegistered()){
|
||||
$this->activeAliases = (array) $aliases;
|
||||
}
|
||||
@ -264,7 +308,7 @@ abstract class Command{
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description){
|
||||
$this->description = $description;
|
||||
$this->commandData->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,6 +325,13 @@ abstract class Command{
|
||||
$this->usageMessage = $usage;
|
||||
}
|
||||
|
||||
public static final function generateDefaultData() : \stdClass{
|
||||
if(self::$defaultDataTemplate === null){
|
||||
self::$defaultDataTemplate = json_decode(file_get_contents(Server::getInstance()->getFilePath() . "src/pocketmine/resources/command_default.json"));
|
||||
}
|
||||
return clone self::$defaultDataTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandSender $source
|
||||
* @param string $message
|
||||
|
@ -23,9 +23,5 @@ namespace pocketmine\entity;
|
||||
|
||||
|
||||
interface Ageable{
|
||||
const DATA_AGEABLE_FLAGS = 14;
|
||||
|
||||
const DATA_FLAG_BABY = 0;
|
||||
|
||||
public function isBaby();
|
||||
}
|
@ -24,14 +24,7 @@ namespace pocketmine\entity;
|
||||
|
||||
abstract class Animal extends Creature implements Ageable{
|
||||
|
||||
public function initEntity(){
|
||||
parent::initEntity();
|
||||
if($this->getDataProperty(self::DATA_AGEABLE_FLAGS) === null){
|
||||
$this->setDataProperty(self::DATA_AGEABLE_FLAGS, self::DATA_TYPE_BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function isBaby(){
|
||||
return $this->getDataFlag(self::DATA_AGEABLE_FLAGS, self::DATA_FLAG_BABY);
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_BABY);
|
||||
}
|
||||
}
|
@ -50,17 +50,18 @@ class Attribute{
|
||||
protected static $attributes = [];
|
||||
|
||||
public static function init(){
|
||||
self::addAttribute(self::ABSORPTION, "generic.absorption", 0.00, 340282346638528859811704183484516925440.00, 0.00);
|
||||
self::addAttribute(self::SATURATION, "player.saturation", 0.00, 20.00, 5.00);
|
||||
self::addAttribute(self::EXHAUSTION, "player.exhaustion", 0.00, 5.00, 0.41);
|
||||
self::addAttribute(self::KNOCKBACK_RESISTANCE, "generic.knockbackResistance", 0.00, 1.00, 0.00);
|
||||
self::addAttribute(self::HEALTH, "generic.health", 0.00, 20.00, 20.00);
|
||||
self::addAttribute(self::MOVEMENT_SPEED, "generic.movementSpeed", 0.00, 340282346638528859811704183484516925440.00, 0.10);
|
||||
self::addAttribute(self::FOLLOW_RANGE, "generic.followRange", 0.00, 2048.00, 16.00, false);
|
||||
self::addAttribute(self::HUNGER, "player.hunger", 0.00, 20.00, 20.00);
|
||||
self::addAttribute(self::ATTACK_DAMAGE, "generic.attackDamage", 0.00, 340282346638528859811704183484516925440.00, 1.00, false);
|
||||
self::addAttribute(self::EXPERIENCE_LEVEL, "player.level", 0.00, 24791.00, 0.00);
|
||||
self::addAttribute(self::EXPERIENCE, "player.experience", 0.00, 1.00, 0.00);
|
||||
self::addAttribute(self::ABSORPTION, "minecraft:absorption", 0.00, 340282346638528859811704183484516925440.00, 0.00);
|
||||
self::addAttribute(self::SATURATION, "minecraft:player.saturation", 0.00, 20.00, 5.00);
|
||||
self::addAttribute(self::EXHAUSTION, "minecraft:player.exhaustion", 0.00, 5.00, 0.41);
|
||||
self::addAttribute(self::KNOCKBACK_RESISTANCE, "minecraft:knockback_resistance", 0.00, 1.00, 0.00);
|
||||
self::addAttribute(self::HEALTH, "minecraft:health", 0.00, 20.00, 20.00);
|
||||
self::addAttribute(self::MOVEMENT_SPEED, "minecraft:movement", 0.00, 340282346638528859811704183484516925440.00, 0.10);
|
||||
self::addAttribute(self::FOLLOW_RANGE, "minecraft:follow_range", 0.00, 2048.00, 16.00, false);
|
||||
self::addAttribute(self::HUNGER, "minecraft:player.hunger", 0.00, 20.00, 20.00);
|
||||
self::addAttribute(self::ATTACK_DAMAGE, "minecraft:attack_damage", 0.00, 340282346638528859811704183484516925440.00, 1.00, false);
|
||||
self::addAttribute(self::EXPERIENCE_LEVEL, "minecraft:player.level", 0.00, 24791.00, 0.00);
|
||||
self::addAttribute(self::EXPERIENCE, "minecraft:player.experience", 0.00, 1.00, 0.00);
|
||||
//TODO: minecraft:luck (for fishing?)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,10 @@ class AttributeMap implements \ArrayAccess{
|
||||
return $this->attributes[$id] ?? null;
|
||||
}
|
||||
|
||||
public function getAll(): array{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attribute[]
|
||||
*/
|
||||
|
@ -269,7 +269,7 @@ class Effect{
|
||||
|
||||
if($this->id === Effect::INVISIBILITY){
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true);
|
||||
$entity->setDataProperty(Entity::DATA_SHOW_NAMETAG, Entity::DATA_TYPE_BYTE, 0);
|
||||
$entity->setNameTagVisible(false);
|
||||
}elseif($this->id === Effect::SPEED){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
if($modify and $oldEffect !== null){
|
||||
@ -303,7 +303,7 @@ class Effect{
|
||||
|
||||
if($this->id === Effect::INVISIBILITY){
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
|
||||
$entity->setDataProperty(Entity::DATA_SHOW_NAMETAG, Entity::DATA_TYPE_BYTE, 1);
|
||||
$entity->setNameTagVisible(true);
|
||||
}elseif($this->id === Effect::SPEED){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
$attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier));
|
||||
|
@ -62,10 +62,8 @@ use pocketmine\Server;
|
||||
|
||||
abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
|
||||
const NETWORK_ID = -1;
|
||||
|
||||
|
||||
const DATA_TYPE_BYTE = 0;
|
||||
const DATA_TYPE_SHORT = 1;
|
||||
const DATA_TYPE_INT = 2;
|
||||
@ -74,16 +72,42 @@ abstract class Entity extends Location implements Metadatable{
|
||||
const DATA_TYPE_SLOT = 5;
|
||||
const DATA_TYPE_POS = 6;
|
||||
const DATA_TYPE_LONG = 7;
|
||||
const DATA_TYPE_VECTOR3F = 8;
|
||||
|
||||
const DATA_FLAGS = 0;
|
||||
const DATA_AIR = 1;
|
||||
const DATA_NAMETAG = 2;
|
||||
const DATA_SHOW_NAMETAG = 3;
|
||||
const DATA_SILENT = 4;
|
||||
const DATA_POTION_COLOR = 7;
|
||||
const DATA_POTION_AMBIENT = 8;
|
||||
const DATA_NO_AI = 15;
|
||||
const DATA_LINKED_EID = 23;
|
||||
//1 (int)
|
||||
const DATA_VARIANT = 2; //int
|
||||
const DATA_COLOUR = 3; //byte
|
||||
const DATA_NAMETAG = 4; //string
|
||||
const DATA_OWNER_EID = 5; //long
|
||||
|
||||
const DATA_AIR = 7; //short
|
||||
const DATA_POTION_COLOR = 8; //int (ARGB!)
|
||||
const DATA_POTION_AMBIENT = 9; //byte
|
||||
|
||||
/* 27 (byte) player-specific flags
|
||||
* 28 (int) player "index"?
|
||||
* 29 (block coords) bed position */
|
||||
const DATA_LEAD_HOLDER_EID = 38; //long
|
||||
const DATA_SCALE = 39; //float
|
||||
const DATA_INTERACTIVE_TAG = 40; //string (button text)
|
||||
/* 41 (long) */
|
||||
const DATA_URL_TAG = 43; //string
|
||||
const DATA_MAX_AIR = 44; //short
|
||||
const DATA_MARK_VARIANT = 45; //int
|
||||
/* 46 (byte)
|
||||
* 47 (int)
|
||||
* 48 (int)
|
||||
* 49 (long)
|
||||
* 50 (long)
|
||||
* 51 (long)
|
||||
* 52 (short) */
|
||||
const DATA_BOUNDING_BOX_WIDTH = 53; //float
|
||||
const DATA_BOUNDING_BOX_HEIGHT = 54; //float
|
||||
/* 56 (vector3f)
|
||||
* 57 (byte)
|
||||
* 58 (float)
|
||||
* 59 (float) */
|
||||
|
||||
|
||||
const DATA_FLAG_ONFIRE = 0;
|
||||
@ -92,7 +116,33 @@ abstract class Entity extends Location implements Metadatable{
|
||||
const DATA_FLAG_SPRINTING = 3;
|
||||
const DATA_FLAG_ACTION = 4;
|
||||
const DATA_FLAG_INVISIBLE = 5;
|
||||
|
||||
const DATA_FLAG_TEMPTED = 6; //???
|
||||
const DATA_FLAG_INLOVE = 7;
|
||||
const DATA_FLAG_SADDLED = 8;
|
||||
const DATA_FLAG_POWERED = 9;
|
||||
const DATA_FLAG_IGNITED = 10; //for creepers?
|
||||
const DATA_FLAG_BABY = 11;
|
||||
const DATA_FLAG_CONVERTING = 12; //???
|
||||
const DATA_FLAG_CRITICAL = 13;
|
||||
const DATA_FLAG_CAN_SHOW_NAMETAG = 14;
|
||||
const DATA_FLAG_ALWAYS_SHOW_NAMETAG = 15;
|
||||
const DATA_FLAG_IMMOBILE = 16, DATA_FLAG_NO_AI = 16;
|
||||
const DATA_FLAG_SILENT = 17;
|
||||
const DATA_FLAG_WALLCLIMBING = 18;
|
||||
const DATA_FLAG_RESTING = 19; //for bats?
|
||||
const DATA_FLAG_SITTING = 20;
|
||||
const DATA_FLAG_ANGRY = 21;
|
||||
const DATA_FLAG_INTERESTED = 22; //for mobs following players with food?
|
||||
const DATA_FLAG_CHARGED = 23;
|
||||
const DATA_FLAG_TAMED = 24;
|
||||
const DATA_FLAG_LEASHED = 25;
|
||||
const DATA_FLAG_SHEARED = 26; //for sheep
|
||||
const DATA_FLAG_FALL_FLYING = 27; //???
|
||||
const DATA_FLAG_ELDER = 28; //elder guardian
|
||||
const DATA_FLAG_MOVING = 29;
|
||||
const DATA_FLAG_BREATHING = 30; //hides bubbles if true
|
||||
const DATA_FLAG_CHESTED = 31; //for mules?
|
||||
const DATA_FLAG_STACKABLE = 32; //???
|
||||
|
||||
public static $entityCount = 1;
|
||||
/** @var Entity[] */
|
||||
@ -111,13 +161,12 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
protected $dataFlags = 0;
|
||||
protected $dataProperties = [
|
||||
self::DATA_FLAGS => [self::DATA_TYPE_BYTE, 0],
|
||||
self::DATA_AIR => [self::DATA_TYPE_SHORT, 300],
|
||||
self::DATA_FLAGS => [self::DATA_TYPE_LONG, 0],
|
||||
self::DATA_AIR => [self::DATA_TYPE_SHORT, 400],
|
||||
self::DATA_MAX_AIR => [self::DATA_TYPE_SHORT, 400],
|
||||
self::DATA_NAMETAG => [self::DATA_TYPE_STRING, ""],
|
||||
self::DATA_SHOW_NAMETAG => [self::DATA_TYPE_BYTE, 1],
|
||||
self::DATA_SILENT => [self::DATA_TYPE_BYTE, 0],
|
||||
self::DATA_NO_AI => [self::DATA_TYPE_BYTE, 0],
|
||||
self::DATA_LINKED_EID => [self::DATA_TYPE_LONG, -1],
|
||||
self::DATA_LEAD_HOLDER_EID => [self::DATA_TYPE_LONG, -1],
|
||||
self::DATA_SCALE => [self::DATA_TYPE_FLOAT, 1],
|
||||
];
|
||||
|
||||
public $passenger = null;
|
||||
@ -290,9 +339,17 @@ abstract class Entity extends Location implements Metadatable{
|
||||
* @return bool
|
||||
*/
|
||||
public function isNameTagVisible(){
|
||||
return $this->getDataProperty(self::DATA_SHOW_NAMETAG) > 0;
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_CAN_SHOW_NAMETAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNameTagAlwaysVisible(){
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ALWAYS_SHOW_NAMETAG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
@ -304,7 +361,14 @@ abstract class Entity extends Location implements Metadatable{
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setNameTagVisible($value = true){
|
||||
$this->setDataProperty(self::DATA_SHOW_NAMETAG, self::DATA_TYPE_BYTE, $value ? 1 : 0);
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_CAN_SHOW_NAMETAG, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setNameTagAlwaysVisible($value = true){
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ALWAYS_SHOW_NAMETAG, $value);
|
||||
}
|
||||
|
||||
public function isSneaking(){
|
||||
@ -327,6 +391,14 @@ abstract class Entity extends Location implements Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
public function isImmobile() : bool{
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_IMMOBILE);
|
||||
}
|
||||
|
||||
public function setImmobile($value = true) : bool{
|
||||
return $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_IMMOBILE, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Effect[]
|
||||
*/
|
||||
@ -383,6 +455,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
}
|
||||
|
||||
protected function recalculateEffectColor(){
|
||||
//TODO: add transparency values
|
||||
$color = [0, 0, 0]; //RGB
|
||||
$count = 0;
|
||||
$ambient = true;
|
||||
@ -574,14 +647,23 @@ abstract class Entity extends Location implements Metadatable{
|
||||
* @param array $data Properly formatted entity data, defaults to everything
|
||||
*/
|
||||
public function sendData($player, array $data = null){
|
||||
if(!is_array($player)){
|
||||
$player = [$player];
|
||||
}
|
||||
|
||||
$pk = new SetEntityDataPacket();
|
||||
$pk->eid = ($player === $this ? 0 : $this->getId());
|
||||
$pk->eid = $this->getId();
|
||||
$pk->metadata = $data === null ? $this->dataProperties : $data;
|
||||
|
||||
if(!is_array($player)){
|
||||
$player->dataPacket($pk);
|
||||
}else{
|
||||
Server::broadcastPacket($player, $pk);
|
||||
foreach($player as $p){
|
||||
if($p === $this){
|
||||
continue;
|
||||
}
|
||||
$p->dataPacket(clone $pk);
|
||||
}
|
||||
if($this instanceof Player){
|
||||
$pk->eid = 0;
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1567,7 +1649,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
* @param bool $value
|
||||
* @param int $type
|
||||
*/
|
||||
public function setDataFlag($propertyId, $id, $value = true, $type = self::DATA_TYPE_BYTE){
|
||||
public function setDataFlag($propertyId, $id, $value = true, $type = self::DATA_TYPE_LONG){
|
||||
if($this->getDataFlag($propertyId, $id) !== $value){
|
||||
$flags = (int) $this->getDataProperty($propertyId);
|
||||
$flags ^= 1 << $id;
|
||||
|
@ -41,12 +41,13 @@ use pocketmine\Player;
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
|
||||
|
||||
const DATA_PLAYER_FLAG_SLEEP = 1;
|
||||
const DATA_PLAYER_FLAG_DEAD = 2;
|
||||
const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK
|
||||
|
||||
const DATA_PLAYER_FLAGS = 16;
|
||||
const DATA_PLAYER_BED_POSITION = 17;
|
||||
const DATA_PLAYER_FLAGS = 27;
|
||||
|
||||
const DATA_PLAYER_BED_POSITION = 29;
|
||||
|
||||
/** @var PlayerInventory */
|
||||
protected $inventory;
|
||||
@ -253,7 +254,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
|
||||
protected function initEntity(){
|
||||
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||
$this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false, self::DATA_TYPE_BYTE);
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0], false);
|
||||
|
||||
$this->inventory = new PlayerInventory($this);
|
||||
|
@ -178,6 +178,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
public function entityBaseTick($tickDiff = 1){
|
||||
Timings::$timerLivingEntityBaseTick->startTiming();
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_BREATHING, !$this->isInsideOfWater());
|
||||
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
@ -190,7 +191,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
if(!$this->hasEffect(Effect::WATER_BREATHING) and $this->isInsideOfWater()){
|
||||
if($this instanceof WaterAnimal){
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300);
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 400);
|
||||
}else{
|
||||
$hasUpdate = true;
|
||||
$airTicks = $this->getDataProperty(self::DATA_AIR) - $tickDiff;
|
||||
@ -214,7 +215,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
}
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $airTicks);
|
||||
}else{
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300);
|
||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,6 @@ class Villager extends Creature implements NPC, Ageable{
|
||||
}
|
||||
|
||||
public function isBaby(){
|
||||
return $this->getDataFlag(self::DATA_AGEABLE_FLAGS, self::DATA_FLAG_BABY);
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_BABY);
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,8 @@
|
||||
namespace pocketmine\entity;
|
||||
|
||||
abstract class WaterAnimal extends Creature implements Ageable{
|
||||
public function initEntity(){
|
||||
parent::initEntity();
|
||||
if($this->getDataProperty(self::DATA_AGEABLE_FLAGS) === null){
|
||||
$this->setDataProperty(self::DATA_AGEABLE_FLAGS, self::DATA_TYPE_BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function isBaby(){
|
||||
return $this->getDataFlag(self::DATA_AGEABLE_FLAGS, self::DATA_FLAG_BABY);
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_BABY);
|
||||
}
|
||||
}
|
||||
|
42
src/pocketmine/event/player/PlayerToggleFlightEvent.php
Normal file
42
src/pocketmine/event/player/PlayerToggleFlightEvent.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?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\event\player;
|
||||
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\Player;
|
||||
|
||||
class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable{
|
||||
public static $handlerList = null;
|
||||
|
||||
/** @var bool */
|
||||
protected $isFlying;
|
||||
|
||||
public function __construct(Player $player, $isFlying){
|
||||
$this->player = $player;
|
||||
$this->isFlying = (bool) $isFlying;
|
||||
}
|
||||
|
||||
public function isFlying(){
|
||||
return $this->isFlying;
|
||||
}
|
||||
|
||||
}
|
@ -77,7 +77,7 @@ class CraftingManager{
|
||||
case 2:
|
||||
$result = $recipe["Result"];
|
||||
$resultItem = Item::get($result["ID"], $result["Damage"], $result["Count"]);
|
||||
$this->registerRecipe(new FurnaceRecipe($resultItem, Item::get($recipe["Ingredients"], 0, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe($resultItem, Item::get($recipe["Ingredients"], null, 1)));
|
||||
break;
|
||||
case 3:
|
||||
$result = $recipe["Result"];
|
||||
|
@ -227,8 +227,15 @@ class Item implements ItemIds{
|
||||
|
||||
$creativeItems = new Config(Server::getInstance()->getFilePath() . "src/pocketmine/resources/creativeitems.json", Config::JSON, []);
|
||||
|
||||
foreach($creativeItems->getAll() as $item){
|
||||
self::addCreativeItem(Item::get($item["ID"], $item["Damage"]));
|
||||
foreach($creativeItems->getAll() as $data){
|
||||
$item = Item::get($data["id"], $data["damage"]);
|
||||
if($item->getName() === "Unknown"){
|
||||
continue;
|
||||
}
|
||||
if(isset($data["nbt"])){
|
||||
$item->setNamedTag(NBT::parseJson(json_encode($data["nbt"])));
|
||||
}
|
||||
self::addCreativeItem($item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +248,7 @@ class Item implements ItemIds{
|
||||
}
|
||||
|
||||
public static function addCreativeItem(Item $item){
|
||||
Item::$creative[] = Item::get($item->getId(), $item->getDamage());
|
||||
Item::$creative[] = clone $item;
|
||||
}
|
||||
|
||||
public static function removeCreativeItem(Item $item){
|
||||
|
@ -723,9 +723,14 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
foreach($this->motionToSend as $index => $entry){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->entities = $entry;
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
foreach($entry as $entity){
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->eid = $entity[0];
|
||||
$pk->motionX = $entity[1];
|
||||
$pk->motionY = $entity[2];
|
||||
$pk->motionZ = $entity[3];
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
}
|
||||
}
|
||||
$this->motionToSend = [];
|
||||
|
||||
|
@ -86,7 +86,7 @@ class Anvil extends McRegion{
|
||||
}
|
||||
}
|
||||
$nbt->setData($list);
|
||||
$tiles = $nbt->write();
|
||||
$tiles = $nbt->write(true);
|
||||
}
|
||||
|
||||
$extraData = new BinaryStream();
|
||||
|
@ -49,7 +49,7 @@ class ChunkRequestTask extends AsyncTask{
|
||||
foreach($chunk->getTiles() as $tile){
|
||||
if($tile instanceof Spawnable){
|
||||
$nbt->setData($tile->getSpawnCompound());
|
||||
$tiles .= $nbt->write();
|
||||
$tiles .= $nbt->write(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ class McRegion extends BaseLevelProvider{
|
||||
}
|
||||
}
|
||||
$nbt->setData($list);
|
||||
$tiles = $nbt->write();
|
||||
$tiles = $nbt->write(true);
|
||||
}
|
||||
|
||||
$extraData = new BinaryStream();
|
||||
|
@ -89,11 +89,14 @@ class FloatingTextParticle extends Particle{
|
||||
$pk->pitch = 0;
|
||||
$pk->item = 0;
|
||||
$pk->meta = 0;
|
||||
$flags = 0;
|
||||
$flags |= 1 << Entity::DATA_FLAG_INVISIBLE;
|
||||
$flags |= 1 << Entity::DATA_FLAG_CAN_SHOW_NAMETAG;
|
||||
$flags |= 1 << Entity::DATA_FLAG_ALWAYS_SHOW_NAMETAG;
|
||||
$flags |= 1 << Entity::DATA_FLAG_IMMOBILE;
|
||||
$pk->metadata = [
|
||||
Entity::DATA_FLAGS => [Entity::DATA_TYPE_BYTE, 1 << Entity::DATA_FLAG_INVISIBLE],
|
||||
Entity::DATA_FLAGS => [Entity::DATA_TYPE_LONG, $flags],
|
||||
Entity::DATA_NAMETAG => [Entity::DATA_TYPE_STRING, $this->title . ($this->text !== "" ? "\n" . $this->text : "")],
|
||||
Entity::DATA_SHOW_NAMETAG => [Entity::DATA_TYPE_BYTE, 1],
|
||||
Entity::DATA_NO_AI => [Entity::DATA_TYPE_BYTE, 1]
|
||||
];
|
||||
|
||||
$p[] = $pk;
|
||||
|
@ -463,14 +463,14 @@ class NBT{
|
||||
$this->endianness = $endianness & 0x01;
|
||||
}
|
||||
|
||||
public function read($buffer, $doMultiple = false){
|
||||
public function read($buffer, $doMultiple = false, bool $network = false){
|
||||
$this->offset = 0;
|
||||
$this->buffer = $buffer;
|
||||
$this->data = $this->readTag();
|
||||
$this->data = $this->readTag($network);
|
||||
if($doMultiple and $this->offset < strlen($this->buffer)){
|
||||
$this->data = [$this->data];
|
||||
do{
|
||||
$this->data[] = $this->readTag();
|
||||
$this->data[] = $this->readTag($network);
|
||||
}while($this->offset < strlen($this->buffer));
|
||||
}
|
||||
$this->buffer = "";
|
||||
@ -480,20 +480,25 @@ class NBT{
|
||||
$this->read(zlib_decode($buffer));
|
||||
}
|
||||
|
||||
public function readNetworkCompressed($buffer, $compression = ZLIB_ENCODING_GZIP){
|
||||
$this->read(zlib_decode($buffer), false, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|bool
|
||||
*/
|
||||
public function write(){
|
||||
public function write(bool $network = false){
|
||||
$this->offset = 0;
|
||||
$this->buffer = "";
|
||||
|
||||
if($this->data instanceof CompoundTag){
|
||||
$this->writeTag($this->data);
|
||||
$this->writeTag($this->data, $network);
|
||||
|
||||
return $this->buffer;
|
||||
}elseif(is_array($this->data)){
|
||||
foreach($this->data as $tag){
|
||||
$this->writeTag($tag);
|
||||
$this->writeTag($tag, $network);
|
||||
}
|
||||
return $this->buffer;
|
||||
}
|
||||
@ -509,51 +514,64 @@ class NBT{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function readTag(){
|
||||
switch($this->getByte()){
|
||||
public function writeNetworkCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){
|
||||
if(($write = $this->write(true)) !== false){
|
||||
return zlib_encode($write, $compression, $level);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function readTag(bool $network = false){
|
||||
if($this->feof()){
|
||||
$tagType = -1; //prevent crashes for empty tags
|
||||
}else{
|
||||
$tagType = $this->getByte();
|
||||
}
|
||||
switch($tagType){
|
||||
case NBT::TAG_Byte:
|
||||
$tag = new ByteTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new ByteTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Short:
|
||||
$tag = new ShortTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new ShortTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Int:
|
||||
$tag = new IntTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new IntTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Long:
|
||||
$tag = new LongTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new LongTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Float:
|
||||
$tag = new FloatTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new FloatTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Double:
|
||||
$tag = new DoubleTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new DoubleTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_ByteArray:
|
||||
$tag = new ByteArrayTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new ByteArrayTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_String:
|
||||
$tag = new StringTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new StringTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_List:
|
||||
$tag = new ListTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new ListTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_Compound:
|
||||
$tag = new CompoundTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new CompoundTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
case NBT::TAG_IntArray:
|
||||
$tag = new IntArrayTag($this->getString());
|
||||
$tag->read($this);
|
||||
$tag = new IntArrayTag($this->getString($network));
|
||||
$tag->read($this, $network);
|
||||
break;
|
||||
|
||||
case NBT::TAG_End: //No named tag
|
||||
@ -564,12 +582,12 @@ class NBT{
|
||||
return $tag;
|
||||
}
|
||||
|
||||
public function writeTag(Tag $tag){
|
||||
public function writeTag(Tag $tag, bool $network = false){
|
||||
$this->putByte($tag->getType());
|
||||
if($tag instanceof NamedTAG){
|
||||
$this->putString($tag->getName());
|
||||
$this->putString($tag->getName(), $network);
|
||||
}
|
||||
$tag->write($this);
|
||||
$tag->write($this, $network);
|
||||
}
|
||||
|
||||
public function getByte(){
|
||||
@ -588,12 +606,19 @@ class NBT{
|
||||
$this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeShort($v) : Binary::writeLShort($v);
|
||||
}
|
||||
|
||||
public function getInt(){
|
||||
public function getInt(bool $network = false){
|
||||
if($network === true){
|
||||
return Binary::readVarInt($this);
|
||||
}
|
||||
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 ? Binary::writeInt($v) : Binary::writeLInt($v);
|
||||
public function putInt($v, bool $network = false){
|
||||
if($network === true){
|
||||
$this->buffer .= Binary::writeVarInt($v);
|
||||
}else{
|
||||
$this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeInt($v) : Binary::writeLInt($v);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLong(){
|
||||
@ -620,12 +645,17 @@ class NBT{
|
||||
$this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeDouble($v) : Binary::writeLDouble($v);
|
||||
}
|
||||
|
||||
public function getString(){
|
||||
return $this->get($this->getShort());
|
||||
public function getString(bool $network = false){
|
||||
$len = $network ? $this->getByte() : $this->getShort();
|
||||
return $this->get($len);
|
||||
}
|
||||
|
||||
public function putString($v){
|
||||
$this->putShort(strlen($v));
|
||||
public function putString($v, bool $network = false){
|
||||
if($network === true){
|
||||
$this->putByte(strlen($v));
|
||||
}else{
|
||||
$this->putShort(strlen($v));
|
||||
}
|
||||
$this->buffer .= $v;
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,12 @@ class ByteArrayTag extends NamedTag{
|
||||
return NBT::TAG_ByteArray;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
$this->value = $nbt->get($nbt->getInt());
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->get($nbt->getInt($network));
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
$nbt->putInt(strlen($this->value));
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putInt(strlen($this->value), $network);
|
||||
$nbt->put($this->value);
|
||||
}
|
||||
}
|
@ -31,11 +31,11 @@ class ByteTag extends NamedTag{
|
||||
return NBT::TAG_Byte;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getByte();
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putByte($this->value);
|
||||
}
|
||||
}
|
@ -83,23 +83,23 @@ class CompoundTag extends NamedTag implements \ArrayAccess{
|
||||
return NBT::TAG_Compound;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = [];
|
||||
do{
|
||||
$tag = $nbt->readTag();
|
||||
$tag = $nbt->readTag($network);
|
||||
if($tag instanceof NamedTag and $tag->getName() !== ""){
|
||||
$this->{$tag->getName()} = $tag;
|
||||
}
|
||||
}while(!($tag instanceof EndTag) and !$nbt->feof());
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
foreach($this as $tag){
|
||||
if($tag instanceof Tag and !($tag instanceof EndTag)){
|
||||
$nbt->writeTag($tag);
|
||||
$nbt->writeTag($tag, $network);
|
||||
}
|
||||
}
|
||||
$nbt->writeTag(new EndTag);
|
||||
$nbt->writeTag(new EndTag, $network);
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
|
@ -31,11 +31,11 @@ class DoubleTag extends NamedTag{
|
||||
return NBT::TAG_Double;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getDouble();
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putDouble($this->value);
|
||||
}
|
||||
}
|
@ -29,11 +29,11 @@ class EndTag extends Tag{
|
||||
return NBT::TAG_End;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
|
||||
}
|
||||
}
|
@ -31,11 +31,11 @@ class FloatTag extends NamedTag{
|
||||
return NBT::TAG_Float;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getFloat();
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putFloat($this->value);
|
||||
}
|
||||
}
|
@ -31,13 +31,13 @@ class IntArrayTag extends NamedTag{
|
||||
return NBT::TAG_IntArray;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
$size = $nbt->getInt();
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$size = $nbt->getInt($network);
|
||||
$this->value = array_values(unpack($nbt->endianness === NBT::LITTLE_ENDIAN ? "V*" : "N*", $nbt->get($size * 4)));
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
$nbt->putInt(count($this->value));
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putInt(count($this->value), $network);
|
||||
$nbt->put(pack($nbt->endianness === NBT::LITTLE_ENDIAN ? "V*" : "N*", ...$this->value));
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,11 @@ class IntTag extends NamedTag{
|
||||
return NBT::TAG_Int;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
$this->value = $nbt->getInt();
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getInt($network);
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
$nbt->putInt($this->value);
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putInt($this->value, $network);
|
||||
}
|
||||
}
|
@ -114,72 +114,72 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{
|
||||
return $this->tagType;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = [];
|
||||
$this->tagType = $nbt->getByte();
|
||||
$size = $nbt->getInt();
|
||||
$size = $nbt->getInt($network);
|
||||
for($i = 0; $i < $size and !$nbt->feof(); ++$i){
|
||||
switch($this->tagType){
|
||||
case NBT::TAG_Byte:
|
||||
$tag = new ByteTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Short:
|
||||
$tag = new ShortTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Int:
|
||||
$tag = new IntTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Long:
|
||||
$tag = new LongTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Float:
|
||||
$tag = new FloatTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Double:
|
||||
$tag = new DoubleTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_ByteArray:
|
||||
$tag = new ByteArrayTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_String:
|
||||
$tag = new StringTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_List:
|
||||
$tag = new TagEnum("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_Compound:
|
||||
$tag = new CompoundTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
case NBT::TAG_IntArray:
|
||||
$tag = new IntArrayTag("");
|
||||
$tag->read($nbt);
|
||||
$tag->read($nbt, $network);
|
||||
$this->{$i} = $tag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
if(!isset($this->tagType)){
|
||||
$id = null;
|
||||
foreach($this as $tag){
|
||||
@ -205,7 +205,7 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{
|
||||
}
|
||||
$nbt->putInt(count($tags));
|
||||
foreach($tags as $tag){
|
||||
$tag->write($nbt);
|
||||
$tag->write($nbt, $network);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,13 @@ class LongTag extends NamedTag{
|
||||
return NBT::TAG_Long;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
//TODO: check if this also changed to varint
|
||||
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getLong();
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putLong($this->value);
|
||||
}
|
||||
}
|
@ -31,11 +31,11 @@ class ShortTag extends NamedTag{
|
||||
return NBT::TAG_Short;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getShort();
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putShort($this->value);
|
||||
}
|
||||
}
|
@ -31,12 +31,11 @@ class StringTag extends NamedTag{
|
||||
return NBT::TAG_String;
|
||||
}
|
||||
|
||||
public function read(NBT $nbt){
|
||||
$this->value = $nbt->get($nbt->getShort());
|
||||
public function read(NBT $nbt, bool $network = false){
|
||||
$this->value = $nbt->getString($network);
|
||||
}
|
||||
|
||||
public function write(NBT $nbt){
|
||||
$nbt->putShort(strlen($this->value));
|
||||
$nbt->put($this->value);
|
||||
public function write(NBT $nbt, bool $network = false){
|
||||
$nbt->putString($this->value, $network);
|
||||
}
|
||||
}
|
@ -40,9 +40,9 @@ abstract class Tag extends \stdClass{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
abstract public function write(NBT $nbt);
|
||||
abstract public function write(NBT $nbt, bool $network = false);
|
||||
|
||||
abstract public function read(NBT $nbt);
|
||||
abstract public function read(NBT $nbt, bool $network = false);
|
||||
|
||||
public function __toString(){
|
||||
return (string) $this->value;
|
||||
|
@ -25,16 +25,20 @@
|
||||
namespace pocketmine\network;
|
||||
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\AddHangingEntityPacket;
|
||||
use pocketmine\network\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\protocol\AddItemPacket;
|
||||
use pocketmine\network\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\protocol\AnimatePacket;
|
||||
use pocketmine\network\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\protocol\BatchPacket;
|
||||
use pocketmine\network\protocol\BlockEntityDataPacket;
|
||||
use pocketmine\network\protocol\BlockEventPacket;
|
||||
use pocketmine\network\protocol\ChangeDimensionPacket;
|
||||
use pocketmine\network\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\protocol\CommandStepPacket;
|
||||
use pocketmine\network\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
@ -52,19 +56,27 @@ use pocketmine\network\protocol\HurtArmorPacket;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\protocol\InteractPacket;
|
||||
use pocketmine\network\protocol\InventoryActionPacket;
|
||||
use pocketmine\network\protocol\ItemFrameDropItemPacket;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\protocol\LoginPacket;
|
||||
use pocketmine\network\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\protocol\PlayerInputPacket;
|
||||
use pocketmine\network\protocol\PlayerListPacket;
|
||||
use pocketmine\network\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\protocol\RemoveBlockPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\protocol\ReplaceSelectedItemPacket;
|
||||
use pocketmine\network\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\protocol\ResourcePackClientResponsePacket;
|
||||
use pocketmine\network\protocol\ResourcePacksInfoPacket;
|
||||
use pocketmine\network\protocol\RespawnPacket;
|
||||
use pocketmine\network\protocol\SetCommandsEnabledPacket;
|
||||
use pocketmine\network\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\protocol\SetEntityLinkPacket;
|
||||
@ -73,6 +85,7 @@ use pocketmine\network\protocol\SetHealthPacket;
|
||||
use pocketmine\network\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
use pocketmine\network\protocol\SpawnExperienceOrbPacket;
|
||||
use pocketmine\network\protocol\StartGamePacket;
|
||||
use pocketmine\network\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\network\protocol\TextPacket;
|
||||
@ -81,6 +94,7 @@ use pocketmine\network\protocol\UseItemPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
|
||||
class Network{
|
||||
|
||||
@ -208,18 +222,25 @@ class Network{
|
||||
}
|
||||
|
||||
public function processBatch(BatchPacket $packet, Player $p){
|
||||
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
||||
$len = strlen($str);
|
||||
$offset = 0;
|
||||
try{
|
||||
while($offset < $len){
|
||||
$pkLen = Binary::readInt(substr($str, $offset, 4));
|
||||
$offset += 4;
|
||||
if(strlen($packet->payload) === 0){
|
||||
//prevent zlib_decode errors for incorrectly-decoded packets
|
||||
throw new \InvalidArgumentException("BatchPacket payload is empty or packet decode error");
|
||||
}
|
||||
|
||||
$buf = substr($str, $offset, $pkLen);
|
||||
$offset += $pkLen;
|
||||
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
||||
$len = strlen($str);
|
||||
|
||||
if(($pk = $this->getPacket(ord($buf{0}))) !== null){ // #blameshoghi
|
||||
if($len === 0){
|
||||
throw new \InvalidStateException("Decoded BatchPacket payload is empty");
|
||||
}
|
||||
|
||||
$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){
|
||||
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
|
||||
}
|
||||
@ -227,11 +248,8 @@ class Network{
|
||||
$pk->setBuffer($buf, 1);
|
||||
|
||||
$pk->decode();
|
||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread in " . get_class($pk));
|
||||
$p->handleDataPacket($pk);
|
||||
|
||||
if($pk->getOffset() <= 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
@ -284,56 +302,69 @@ class Network{
|
||||
private function registerPackets(){
|
||||
$this->packetPool = new \SplFixedArray(256);
|
||||
|
||||
$this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAY_STATUS_PACKET, PlayStatusPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::DISCONNECT_PACKET, DisconnectPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BATCH_PACKET, BatchPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TEXT_PACKET, TextPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_TIME_PACKET, SetTimePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::START_GAME_PACKET, StartGamePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_PLAYER_PACKET, AddPlayerPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_ENTITY_PACKET, AddEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_ENTITY_PACKET, RemoveEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_HANGING_ENTITY_PACKET, AddHangingEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_ITEM_ENTITY_PACKET, AddItemEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOVE_ENTITY_PACKET, MoveEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOVE_PLAYER_PACKET, MovePlayerPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_BLOCK_PACKET, RemoveBlockPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::UPDATE_BLOCK_PACKET, UpdateBlockPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_ITEM_PACKET, AddItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_PAINTING_PACKET, AddPaintingPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::EXPLODE_PACKET, ExplodePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LEVEL_EVENT_PACKET, LevelEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_EVENT_PACKET, BlockEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ENTITY_EVENT_PACKET, EntityEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_EQUIPMENT_PACKET, MobEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET, MobArmorEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::INTERACT_PACKET, InteractPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::USE_ITEM_PACKET, UseItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_ACTION_PACKET, PlayerActionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::HURT_ARMOR_PACKET, HurtArmorPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_DATA_PACKET, SetEntityDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_MOTION_PACKET, SetEntityMotionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_LINK_PACKET, SetEntityLinkPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_HEALTH_PACKET, SetHealthPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_SPAWN_POSITION_PACKET, SetSpawnPositionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADD_PLAYER_PACKET, AddPlayerPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADVENTURE_SETTINGS_PACKET, AdventureSettingsPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ANIMATE_PACKET, AnimatePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESPAWN_PACKET, RespawnPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::DROP_ITEM_PACKET, DropItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_OPEN_PACKET, ContainerOpenPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::AVAILABLE_COMMANDS_PACKET, AvailableCommandsPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BATCH_PACKET, BatchPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_ENTITY_DATA_PACKET, BlockEntityDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_EVENT_PACKET, BlockEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHANGE_DIMENSION_PACKET, ChangeDimensionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::COMMAND_STEP_PACKET, CommandStepPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_CLOSE_PACKET, ContainerClosePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_SET_SLOT_PACKET, ContainerSetSlotPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_SET_DATA_PACKET, ContainerSetDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_OPEN_PACKET, ContainerOpenPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_SET_CONTENT_PACKET, ContainerSetContentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_SET_DATA_PACKET, ContainerSetDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_SET_SLOT_PACKET, ContainerSetSlotPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CRAFTING_DATA_PACKET, CraftingDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CRAFTING_EVENT_PACKET, CraftingEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ADVENTURE_SETTINGS_PACKET, AdventureSettingsPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_ENTITY_DATA_PACKET, BlockEntityDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::DISCONNECT_PACKET, DisconnectPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::DROP_ITEM_PACKET, DropItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ENTITY_EVENT_PACKET, EntityEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::EXPLODE_PACKET, ExplodePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::FULL_CHUNK_DATA_PACKET, FullChunkDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_DIFFICULTY_PACKET, SetDifficultyPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_PLAYER_GAMETYPE_PACKET, SetPlayerGameTypePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHANGE_DIMENSION_PACKET, ChangeDimensionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::HURT_ARMOR_PACKET, HurtArmorPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::INTERACT_PACKET, InteractPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::INVENTORY_ACTION_PACKET, InventoryActionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::ITEM_FRAME_DROP_ITEM_PACKET, ItemFrameDropItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LEVEL_EVENT_PACKET, LevelEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LEVEL_SOUND_EVENT_PACKET, LevelSoundEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET, MobArmorEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_EQUIPMENT_PACKET, MobEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOVE_ENTITY_PACKET, MoveEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOVE_PLAYER_PACKET, MovePlayerPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_ACTION_PACKET, PlayerActionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_INPUT_PACKET, PlayerInputPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_LIST_PACKET, PlayerListPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAY_STATUS_PACKET, PlayStatusPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_BLOCK_PACKET, RemoveBlockPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_ENTITY_PACKET, RemoveEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REPLACE_SELECTED_ITEM_PACKET, ReplaceSelectedItemPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET, RequestChunkRadiusPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACK_CLIENT_RESPONSE_PACKET, ResourcePackClientResponsePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACKS_INFO_PACKET, ResourcePacksInfoPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESPAWN_PACKET, RespawnPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_COMMANDS_ENABLED_PACKET, SetCommandsEnabledPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_DIFFICULTY_PACKET, SetDifficultyPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_DATA_PACKET, SetEntityDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_LINK_PACKET, SetEntityLinkPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_MOTION_PACKET, SetEntityMotionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_HEALTH_PACKET, SetHealthPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET, SetPlayerGameTypePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_SPAWN_POSITION_PACKET, SetSpawnPositionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_TIME_PACKET, SetTimePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET, SpawnExperienceOrbPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::START_GAME_PACKET, StartGamePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TEXT_PACKET, TextPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::UPDATE_BLOCK_PACKET, UpdateBlockPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::USE_ITEM_PACKET, UseItemPacket::class);
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
||||
$pk = $this->getPacket($packet->buffer);
|
||||
if($pk !== null){
|
||||
$pk->decode();
|
||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread!");
|
||||
$this->players[$identifier]->handleDataPacket($pk);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class AddEntityPacket extends DataPacket{
|
||||
public $yaw;
|
||||
public $pitch;
|
||||
public $modifiers;
|
||||
public $metadata;
|
||||
public $metadata = [];
|
||||
public $links = [];
|
||||
|
||||
public function decode(){
|
||||
@ -51,23 +51,20 @@ class AddEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putInt($this->type);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putFloat($this->speedX);
|
||||
$this->putFloat($this->speedY);
|
||||
$this->putFloat($this->speedZ);
|
||||
$this->putFloat($this->yaw * (256 / 360));
|
||||
$this->putFloat($this->pitch * (256 / 360));
|
||||
$this->putInt($this->modifiers);
|
||||
$this->putEntityId($this->eid); //EntityUniqueID - TODO: verify this
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putUnsignedVarInt($this->type);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
$this->putLFloat($this->yaw * (256 / 360));
|
||||
$this->putLFloat($this->pitch * (256 / 360));
|
||||
$this->putUnsignedVarInt($this->modifiers); //attributes?
|
||||
$meta = Binary::writeMetadata($this->metadata);
|
||||
$this->put($meta);
|
||||
$this->putShort(count($this->links));
|
||||
$this->putUnsignedVarInt(count($this->links));
|
||||
foreach($this->links as $link){
|
||||
$this->putLong($link[0]);
|
||||
$this->putLong($link[1]);
|
||||
$this->putEntityId($link[0]);
|
||||
$this->putEntityId($link[1]);
|
||||
$this->putByte($link[2]);
|
||||
}
|
||||
}
|
||||
|
48
src/pocketmine/network/protocol/AddHangingEntityPacket.php
Normal file
48
src/pocketmine/network/protocol/AddHangingEntityPacket.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class AddHangingEntityPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_HANGING_ENTITY_PACKET;
|
||||
|
||||
public $entityUniqueId;
|
||||
public $entityRuntimeId;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $unknown;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->entityUniqueId);
|
||||
$this->putEntityId($this->entityRuntimeId);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->unknown);
|
||||
}
|
||||
|
||||
}
|
@ -42,14 +42,11 @@ class AddItemEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putSlot($this->item);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putFloat($this->speedX);
|
||||
$this->putFloat($this->speedY);
|
||||
$this->putFloat($this->speedZ);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
}
|
||||
|
||||
}
|
||||
|
41
src/pocketmine/network/protocol/AddItemPacket.php
Normal file
41
src/pocketmine/network/protocol/AddItemPacket.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class AddItemPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_ITEM_PACKET;
|
||||
|
||||
public $item;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putSlot($this->item);
|
||||
}
|
||||
|
||||
}
|
@ -40,11 +40,10 @@ class AddPaintingPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putInt($this->direction);
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->direction);
|
||||
$this->putString($this->title);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class AddPlayerPacket extends DataPacket{
|
||||
public $pitch;
|
||||
public $yaw;
|
||||
public $item;
|
||||
public $metadata;
|
||||
public $metadata = [];
|
||||
|
||||
public function decode(){
|
||||
|
||||
@ -53,16 +53,14 @@ class AddPlayerPacket extends DataPacket{
|
||||
$this->reset();
|
||||
$this->putUUID($this->uuid);
|
||||
$this->putString($this->username);
|
||||
$this->putLong($this->eid);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putFloat($this->speedX);
|
||||
$this->putFloat($this->speedY);
|
||||
$this->putFloat($this->speedZ);
|
||||
$this->putFloat($this->yaw);
|
||||
$this->putFloat($this->yaw); //TODO headrot
|
||||
$this->putFloat($this->pitch);
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
//TODO: check these are in the right order
|
||||
$this->putLFloat($this->yaw);
|
||||
$this->putLFloat($this->yaw); //TODO headrot
|
||||
$this->putLFloat($this->pitch);
|
||||
$this->putSlot($this->item);
|
||||
|
||||
$meta = Binary::writeMetadata($this->metadata);
|
||||
|
@ -27,19 +27,71 @@ namespace pocketmine\network\protocol;
|
||||
class AdventureSettingsPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADVENTURE_SETTINGS_PACKET;
|
||||
|
||||
public $flags;
|
||||
const PERMISSION_NORMAL = 0;
|
||||
const PERMISSION_OPERATOR = 1;
|
||||
const PERMISSION_HOST = 2;
|
||||
const PERMISSION_AUTOMATION = 3;
|
||||
const PERMISSION_ADMIN = 4;
|
||||
|
||||
public $worldImmutable;
|
||||
public $noPvp;
|
||||
public $noPvm;
|
||||
public $noMvp;
|
||||
|
||||
public $autoJump;
|
||||
public $allowFlight;
|
||||
public $noClip;
|
||||
public $isFlying;
|
||||
|
||||
/*
|
||||
bit mask | flag name
|
||||
0x00000001 world_immutable
|
||||
0x00000002 no_pvp
|
||||
0x00000004 no_pvm
|
||||
0x00000008 no_mvp
|
||||
0x00000010 ?
|
||||
0x00000020 auto_jump
|
||||
0x00000040 allow_fly
|
||||
0x00000080 noclip
|
||||
0x00000100 ?
|
||||
0x00000200 is_flying
|
||||
*/
|
||||
|
||||
public $flags = 0;
|
||||
public $userPermission;
|
||||
public $globalPermission;
|
||||
|
||||
public function decode(){
|
||||
$this->flags = $this->getUnsignedVarInt();
|
||||
$this->userPermission = $this->getUnsignedVarInt();
|
||||
|
||||
$this->worldImmutable = (bool) ($this->flags & 1);
|
||||
$this->noPvp = (bool) ($this->flags & (1 << 1));
|
||||
$this->noPvm = (bool) ($this->flags & (1 << 2));
|
||||
$this->noMvp = (bool) ($this->flags & (1 << 3));
|
||||
|
||||
$this->autoJump = (bool) ($this->flags & (1 << 5));
|
||||
$this->allowFlight = (bool) ($this->flags & (1 << 6));
|
||||
$this->noClip = (bool) ($this->flags & (1 << 7));
|
||||
|
||||
$this->isFlying = (bool) ($this->flags & (1 << 9));
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->flags);
|
||||
$this->putInt($this->userPermission);
|
||||
$this->putInt($this->globalPermission);
|
||||
|
||||
$this->flags |= ((int) $this->worldImmutable);
|
||||
$this->flags |= ((int) $this->noPvp) << 1;
|
||||
$this->flags |= ((int) $this->noPvm) << 2;
|
||||
$this->flags |= ((int) $this->noMvp) << 3;
|
||||
|
||||
$this->flags |= ((int) $this->autoJump) << 5;
|
||||
$this->flags |= ((int) $this->allowFlight) << 6;
|
||||
$this->flags |= ((int) $this->noClip) << 7;
|
||||
|
||||
$this->flags |= ((int) $this->isFlying) << 9;
|
||||
|
||||
$this->putUnsignedVarInt($this->flags);
|
||||
$this->putUnsignedVarInt($this->userPermission);
|
||||
}
|
||||
|
||||
}
|
@ -31,14 +31,14 @@ class AnimatePacket extends DataPacket{
|
||||
public $eid;
|
||||
|
||||
public function decode(){
|
||||
$this->action = $this->getByte();
|
||||
$this->eid = $this->getLong();
|
||||
$this->action = $this->getVarInt();
|
||||
$this->eid = $this->getEntityId();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->action);
|
||||
$this->putLong($this->eid);
|
||||
$this->putVarInt($this->action);
|
||||
$this->putEntityId($this->eid);
|
||||
}
|
||||
|
||||
}
|
||||
|
42
src/pocketmine/network/protocol/AvailableCommandsPacket.php
Normal file
42
src/pocketmine/network/protocol/AvailableCommandsPacket.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class AvailableCommandsPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::AVAILABLE_COMMANDS_PACKET;
|
||||
|
||||
public $commands; //JSON-encoded command data
|
||||
public $unknown;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putString($this->commands);
|
||||
$this->putString($this->unknown);
|
||||
}
|
||||
|
||||
}
|
@ -30,14 +30,12 @@ class BatchPacket extends DataPacket{
|
||||
public $payload;
|
||||
|
||||
public function decode(){
|
||||
$size = $this->getInt();
|
||||
$this->payload = $this->get($size);
|
||||
$this->payload = $this->getString();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt(strlen($this->payload));
|
||||
$this->put($this->payload);
|
||||
$this->putString($this->payload);
|
||||
}
|
||||
|
||||
}
|
@ -33,17 +33,13 @@ class BlockEntityDataPacket extends DataPacket{
|
||||
public $namedtag;
|
||||
|
||||
public function decode(){
|
||||
$this->x = $this->getInt();
|
||||
$this->y = $this->getInt();
|
||||
$this->z = $this->getInt();
|
||||
$this->getBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->namedtag = $this->get(true);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->put($this->namedtag);
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,9 @@ class BlockEventPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putInt($this->case1);
|
||||
$this->putInt($this->case2);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->case1);
|
||||
$this->putVarInt($this->case2);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class ChangeDimensionPacket extends DataPacket{
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $unknown;
|
||||
public $unknown; //bool
|
||||
|
||||
public function decode(){
|
||||
|
||||
@ -42,11 +42,9 @@ class ChangeDimensionPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->dimension);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putByte($this->unknown);
|
||||
$this->putVarInt($this->dimension);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putBool($this->unknown);
|
||||
}
|
||||
|
||||
}
|
@ -34,7 +34,7 @@ class ChunkRadiusUpdatedPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->radius);
|
||||
$this->putVarInt($this->radius);
|
||||
}
|
||||
|
||||
}
|
||||
|
68
src/pocketmine/network/protocol/CommandStepPacket.php
Normal file
68
src/pocketmine/network/protocol/CommandStepPacket.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class CommandStepPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::COMMAND_STEP_PACKET;
|
||||
|
||||
/**
|
||||
* unknown (string)
|
||||
* unknown (string)
|
||||
* unknown (uvarint)
|
||||
* unknown (uvarint)
|
||||
* unknown (bool)
|
||||
* unknown (uvarint64)
|
||||
* unknown (string)
|
||||
* unknown (string)
|
||||
* https://gist.github.com/dktapps/8285b93af4ca38e0104bfeb9a6c87afd
|
||||
*/
|
||||
|
||||
public $command;
|
||||
public $overload;
|
||||
public $uvarint1;
|
||||
public $uvarint2;
|
||||
public $bool;
|
||||
public $uvarint64;
|
||||
public $args; //JSON formatted command arguments
|
||||
public $string4;
|
||||
|
||||
public function decode(){
|
||||
$this->command = $this->getString();
|
||||
$this->overload = $this->getString();
|
||||
$this->uvarint1 = $this->getUnsignedVarInt();
|
||||
$this->uvarint2 = $this->getUnsignedVarInt();
|
||||
$this->bool = (bool) $this->getByte();
|
||||
$this->uvarint64 = $this->getUnsignedVarInt(); //TODO: varint64
|
||||
$this->args = json_decode($this->getString());
|
||||
$this->string4 = $this->getString();
|
||||
while(!$this->feof()){
|
||||
$this->getByte(); //prevent assertion errors. TODO: find out why there are always 3 extra bytes at the end of this packet.
|
||||
}
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@ class ContainerOpenPacket extends DataPacket{
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $entityId = -1;
|
||||
|
||||
public function decode(){
|
||||
|
||||
@ -42,10 +43,9 @@ class ContainerOpenPacket extends DataPacket{
|
||||
$this->reset();
|
||||
$this->putByte($this->windowid);
|
||||
$this->putByte($this->type);
|
||||
$this->putShort($this->slots);
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putVarInt($this->slots);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putEntityId($this->entityId);
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@ class ContainerSetContentPacket extends DataPacket{
|
||||
const SPECIAL_INVENTORY = 0;
|
||||
const SPECIAL_ARMOR = 0x78;
|
||||
const SPECIAL_CREATIVE = 0x79;
|
||||
const SPECIAL_HOTBAR = 0x7a;
|
||||
|
||||
public $windowid;
|
||||
public $slots = [];
|
||||
@ -43,14 +44,14 @@ class ContainerSetContentPacket extends DataPacket{
|
||||
|
||||
public function decode(){
|
||||
$this->windowid = $this->getByte();
|
||||
$count = $this->getShort();
|
||||
$count = $this->getUnsignedVarInt();
|
||||
for($s = 0; $s < $count and !$this->feof(); ++$s){
|
||||
$this->slots[$s] = $this->getSlot();
|
||||
}
|
||||
if($this->windowid === self::SPECIAL_INVENTORY){
|
||||
$count = $this->getShort();
|
||||
$count = $this->getUnsignedVarInt();
|
||||
for($s = 0; $s < $count and !$this->feof(); ++$s){
|
||||
$this->hotbar[$s] = $this->getInt();
|
||||
$this->hotbar[$s] = $this->getVarInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,17 +59,17 @@ class ContainerSetContentPacket extends DataPacket{
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->windowid);
|
||||
$this->putShort(count($this->slots));
|
||||
$this->putUnsignedVarInt(count($this->slots));
|
||||
foreach($this->slots as $slot){
|
||||
$this->putSlot($slot);
|
||||
}
|
||||
if($this->windowid === self::SPECIAL_INVENTORY and count($this->hotbar) > 0){
|
||||
$this->putShort(count($this->hotbar));
|
||||
$this->putUnsignedVarInt(count($this->hotbar));
|
||||
foreach($this->hotbar as $slot){
|
||||
$this->putInt($slot);
|
||||
$this->putVarInt($slot);
|
||||
}
|
||||
}else{
|
||||
$this->putShort(0);
|
||||
$this->putUnsignedVarInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,8 @@ class ContainerSetDataPacket extends DataPacket{
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->windowid);
|
||||
$this->putShort($this->property);
|
||||
$this->putShort($this->value);
|
||||
$this->putVarInt($this->property);
|
||||
$this->putVarInt($this->value);
|
||||
}
|
||||
|
||||
}
|
@ -36,16 +36,16 @@ class ContainerSetSlotPacket extends DataPacket{
|
||||
|
||||
public function decode(){
|
||||
$this->windowid = $this->getByte();
|
||||
$this->slot = $this->getShort();
|
||||
$this->hotbarSlot = $this->getShort();
|
||||
$this->slot = $this->getVarInt();
|
||||
$this->hotbarSlot = $this->getVarInt();
|
||||
$this->item = $this->getSlot();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->windowid);
|
||||
$this->putShort($this->slot);
|
||||
$this->putShort($this->hotbarSlot);
|
||||
$this->putVarInt($this->slot);
|
||||
$this->putVarInt($this->hotbarSlot);
|
||||
$this->putSlot($this->item);
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,12 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
|
||||
private static function writeShapelessRecipe(ShapelessRecipe $recipe, BinaryStream $stream){
|
||||
$stream->putInt($recipe->getIngredientCount());
|
||||
$stream->putUnsignedVarInt($recipe->getIngredientCount());
|
||||
foreach($recipe->getIngredientList() as $item){
|
||||
$stream->putSlot($item);
|
||||
}
|
||||
|
||||
$stream->putInt(1);
|
||||
$stream->putUnsignedVarInt(1);
|
||||
$stream->putSlot($recipe->getResult());
|
||||
|
||||
$stream->putUUID($recipe->getId());
|
||||
@ -72,8 +72,8 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
|
||||
private static function writeShapedRecipe(ShapedRecipe $recipe, BinaryStream $stream){
|
||||
$stream->putInt($recipe->getWidth());
|
||||
$stream->putInt($recipe->getHeight());
|
||||
$stream->putVarInt($recipe->getWidth());
|
||||
$stream->putVarInt($recipe->getHeight());
|
||||
|
||||
for($z = 0; $z < $recipe->getHeight(); ++$z){
|
||||
for($x = 0; $x < $recipe->getWidth(); ++$x){
|
||||
@ -81,7 +81,7 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
}
|
||||
|
||||
$stream->putInt(1);
|
||||
$stream->putUnsignedVarInt(1);
|
||||
$stream->putSlot($recipe->getResult());
|
||||
|
||||
$stream->putUUID($recipe->getId());
|
||||
@ -90,13 +90,14 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
|
||||
private static function writeFurnaceRecipe(FurnaceRecipe $recipe, BinaryStream $stream){
|
||||
if($recipe->getInput()->getDamage() !== 0){ //Data recipe
|
||||
$stream->putInt(($recipe->getInput()->getId() << 16) | ($recipe->getInput()->getDamage()));
|
||||
if($recipe->getInput()->getDamage() !== null){ //Data recipe
|
||||
$stream->putVarInt($recipe->getInput()->getId());
|
||||
$stream->putVarInt($recipe->getInput()->getDamage());
|
||||
$stream->putSlot($recipe->getResult());
|
||||
|
||||
return CraftingDataPacket::ENTRY_FURNACE_DATA;
|
||||
}else{
|
||||
$stream->putInt($recipe->getInput()->getId());
|
||||
$stream->putVarInt($recipe->getInput()->getId());
|
||||
$stream->putSlot($recipe->getResult());
|
||||
|
||||
return CraftingDataPacket::ENTRY_FURNACE;
|
||||
@ -104,15 +105,15 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
|
||||
private static function writeEnchantList(EnchantmentList $list, BinaryStream $stream){
|
||||
|
||||
//TODO: check this works on 0.16 (cannot currently test)
|
||||
$stream->putByte($list->getSize());
|
||||
for($i = 0; $i < $list->getSize(); ++$i){
|
||||
$entry = $list->getSlot($i);
|
||||
$stream->putInt($entry->getCost());
|
||||
$stream->putByte(count($entry->getEnchantments()));
|
||||
$stream->putUnsignedVarInt($entry->getCost());
|
||||
$stream->putUnsignedVarInt(count($entry->getEnchantments()));
|
||||
foreach($entry->getEnchantments() as $enchantment){
|
||||
$stream->putInt($enchantment->getId());
|
||||
$stream->putInt($enchantment->getLevel());
|
||||
$stream->putUnsignedVarInt($enchantment->getId());
|
||||
$stream->putUnsignedVarInt($enchantment->getLevel());
|
||||
}
|
||||
$stream->putString($entry->getRandomName());
|
||||
}
|
||||
@ -147,24 +148,22 @@ class CraftingDataPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt(count($this->entries));
|
||||
$this->putUnsignedVarInt(count($this->entries));
|
||||
|
||||
$writer = new BinaryStream();
|
||||
foreach($this->entries as $d){
|
||||
$entryType = self::writeEntry($d, $writer);
|
||||
if($entryType >= 0){
|
||||
$this->putInt($entryType);
|
||||
$this->putInt(strlen($writer->getBuffer()));
|
||||
$this->putVarInt($entryType);
|
||||
$this->put($writer->getBuffer());
|
||||
}else{
|
||||
$this->putInt(-1);
|
||||
$this->putInt(0);
|
||||
$this->putVarInt(-1);
|
||||
}
|
||||
|
||||
$writer->reset();
|
||||
}
|
||||
|
||||
$this->putByte($this->cleanRecipes ? 1 : 0);
|
||||
$this->putBool($this->cleanRecipes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,15 +41,15 @@ class CraftingEventPacket extends DataPacket{
|
||||
|
||||
public function decode(){
|
||||
$this->windowId = $this->getByte();
|
||||
$this->type = $this->getInt();
|
||||
$this->type = $this->getVarInt();
|
||||
$this->id = $this->getUUID();
|
||||
|
||||
$size = $this->getInt();
|
||||
$size = $this->getUnsignedVarInt();
|
||||
for($i = 0; $i < $size and $i < 128; ++$i){
|
||||
$this->input[] = $this->getSlot();
|
||||
}
|
||||
|
||||
$size = $this->getInt();
|
||||
$size = $this->getUnsignedVarInt();
|
||||
for($i = 0; $i < $size and $i < 128; ++$i){
|
||||
$this->output[] = $this->getSlot();
|
||||
}
|
||||
|
@ -27,14 +27,17 @@ namespace pocketmine\network\protocol;
|
||||
class DisconnectPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::DISCONNECT_PACKET;
|
||||
|
||||
public $hideDisconnectionScreen = false;
|
||||
public $message;
|
||||
|
||||
public function decode(){
|
||||
$this->hideDisconnectionScreen = $this->getBool();
|
||||
$this->message = $this->getString();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putBool($this->hideDisconnectionScreen);
|
||||
$this->putString($this->message);
|
||||
}
|
||||
|
||||
|
@ -47,16 +47,19 @@ class EntityEventPacket extends DataPacket{
|
||||
|
||||
public $eid;
|
||||
public $event;
|
||||
public $unknown;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->event = $this->getByte();
|
||||
$this->unknown = $this->getVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putByte($this->event);
|
||||
$this->putVarInt($this->unknown);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,16 +44,12 @@ class ExplodePacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putFloat($this->radius);
|
||||
$this->putInt(count($this->records));
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putLFloat($this->radius);
|
||||
$this->putUnsignedVarInt(count($this->records));
|
||||
if(count($this->records) > 0){
|
||||
foreach($this->records as $record){
|
||||
$this->putByte($record->x);
|
||||
$this->putByte($record->y);
|
||||
$this->putByte($record->z);
|
||||
$this->putBlockCoords($record->x, $record->y, $record->z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,11 +41,10 @@ class FullChunkDataPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->chunkX);
|
||||
$this->putInt($this->chunkZ);
|
||||
$this->putVarInt($this->chunkX);
|
||||
$this->putVarInt($this->chunkZ);
|
||||
$this->putByte($this->order);
|
||||
$this->putInt(strlen($this->data));
|
||||
$this->put($this->data);
|
||||
$this->putString($this->data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class HurtArmorPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->health);
|
||||
$this->putVarInt($this->health);
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ interface Info{
|
||||
/**
|
||||
* Actual Minecraft: PE protocol version
|
||||
*/
|
||||
const CURRENT_PROTOCOL = 84;
|
||||
const CURRENT_PROTOCOL = 91;
|
||||
|
||||
const LOGIN_PACKET = 0x01;
|
||||
const PLAY_STATUS_PACKET = 0x02;
|
||||
@ -38,64 +38,79 @@ interface Info{
|
||||
const CLIENT_TO_SERVER_HANDSHAKE_PACKET = 0x04;
|
||||
const DISCONNECT_PACKET = 0x05;
|
||||
const BATCH_PACKET = 0x06;
|
||||
const TEXT_PACKET = 0x07;
|
||||
const SET_TIME_PACKET = 0x08;
|
||||
const START_GAME_PACKET = 0x09;
|
||||
const ADD_PLAYER_PACKET = 0x0a;
|
||||
const ADD_ENTITY_PACKET = 0x0b;
|
||||
const REMOVE_ENTITY_PACKET = 0x0c;
|
||||
const ADD_ITEM_ENTITY_PACKET = 0x0d;
|
||||
const TAKE_ITEM_ENTITY_PACKET = 0x0e;
|
||||
const MOVE_ENTITY_PACKET = 0x0f;
|
||||
const MOVE_PLAYER_PACKET = 0x10;
|
||||
const RIDER_JUMP_PACKET = 0x11;
|
||||
const REMOVE_BLOCK_PACKET = 0x12;
|
||||
const UPDATE_BLOCK_PACKET = 0x13;
|
||||
const ADD_PAINTING_PACKET = 0x14;
|
||||
const EXPLODE_PACKET = 0x15;
|
||||
const LEVEL_EVENT_PACKET = 0x16;
|
||||
const BLOCK_EVENT_PACKET = 0x17;
|
||||
const ENTITY_EVENT_PACKET = 0x18;
|
||||
const MOB_EFFECT_PACKET = 0x19;
|
||||
const UPDATE_ATTRIBUTES_PACKET = 0x1a;
|
||||
const MOB_EQUIPMENT_PACKET = 0x1b;
|
||||
const MOB_ARMOR_EQUIPMENT_PACKET = 0x1c;
|
||||
const INTERACT_PACKET = 0x1e;
|
||||
const USE_ITEM_PACKET = 0x1f;
|
||||
const PLAYER_ACTION_PACKET = 0x20;
|
||||
const HURT_ARMOR_PACKET = 0x21;
|
||||
const SET_ENTITY_DATA_PACKET = 0x22;
|
||||
const SET_ENTITY_MOTION_PACKET = 0x23;
|
||||
const SET_ENTITY_LINK_PACKET = 0x24;
|
||||
const SET_HEALTH_PACKET = 0x25;
|
||||
const SET_SPAWN_POSITION_PACKET = 0x26;
|
||||
const ANIMATE_PACKET = 0x27;
|
||||
const RESPAWN_PACKET = 0x28;
|
||||
const DROP_ITEM_PACKET = 0x29;
|
||||
const CONTAINER_OPEN_PACKET = 0x2a;
|
||||
const CONTAINER_CLOSE_PACKET = 0x2b;
|
||||
const CONTAINER_SET_SLOT_PACKET = 0x2c;
|
||||
const CONTAINER_SET_DATA_PACKET = 0x2d;
|
||||
const CONTAINER_SET_CONTENT_PACKET = 0x2e;
|
||||
const CRAFTING_DATA_PACKET = 0x2f;
|
||||
const CRAFTING_EVENT_PACKET = 0x30;
|
||||
const ADVENTURE_SETTINGS_PACKET = 0x31;
|
||||
const BLOCK_ENTITY_DATA_PACKET = 0x32;
|
||||
const PLAYER_INPUT_PACKET = 0x33;
|
||||
const FULL_CHUNK_DATA_PACKET = 0x34;
|
||||
const SET_DIFFICULTY_PACKET = 0x35;
|
||||
const CHANGE_DIMENSION_PACKET = 0x36;
|
||||
const SET_PLAYER_GAMETYPE_PACKET = 0x37;
|
||||
const PLAYER_LIST_PACKET = 0x38;
|
||||
const TELEMETRY_EVENT_PACKET = 0x39;
|
||||
const SPAWN_EXPERIENCE_ORB_PACKET = 0x3a;
|
||||
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x3b;
|
||||
const MAP_INFO_REQUEST_PACKET = 0x3c;
|
||||
const REQUEST_CHUNK_RADIUS_PACKET = 0x3d;
|
||||
const CHUNK_RADIUS_UPDATED_PACKET = 0x3e;
|
||||
const ITEM_FRAME_DROP_ITEM_PACKET = 0x3f;
|
||||
const REPLACE_SELECTED_ITEM_PACKET = 0x40;
|
||||
const ADD_ITEM_PACKET = 0x41;
|
||||
const RESOURCE_PACKS_INFO_PACKET = 0x07;
|
||||
const RESOURCE_PACK_STACK_PACKET = 0x08;
|
||||
const RESOURCE_PACK_CLIENT_RESPONSE_PACKET = 0x09;
|
||||
const TEXT_PACKET = 0x0a;
|
||||
const SET_TIME_PACKET = 0x0b;
|
||||
const START_GAME_PACKET = 0x0c;
|
||||
const ADD_PLAYER_PACKET = 0x0d;
|
||||
const ADD_ENTITY_PACKET = 0x0e;
|
||||
const REMOVE_ENTITY_PACKET = 0x0f;
|
||||
const ADD_ITEM_ENTITY_PACKET = 0x10;
|
||||
const ADD_HANGING_ENTITY_PACKET = 0x11;
|
||||
const TAKE_ITEM_ENTITY_PACKET = 0x12;
|
||||
const MOVE_ENTITY_PACKET = 0x13;
|
||||
const MOVE_PLAYER_PACKET = 0x14;
|
||||
const RIDER_JUMP_PACKET = 0x15;
|
||||
const REMOVE_BLOCK_PACKET = 0x16;
|
||||
const UPDATE_BLOCK_PACKET = 0x17;
|
||||
const ADD_PAINTING_PACKET = 0x18;
|
||||
const EXPLODE_PACKET = 0x19;
|
||||
const LEVEL_SOUND_EVENT_PACKET = 0x1a;
|
||||
const LEVEL_EVENT_PACKET = 0x1b;
|
||||
const BLOCK_EVENT_PACKET = 0x1c;
|
||||
const ENTITY_EVENT_PACKET = 0x1d;
|
||||
const MOB_EFFECT_PACKET = 0x1e;
|
||||
const UPDATE_ATTRIBUTES_PACKET = 0x1f;
|
||||
const MOB_EQUIPMENT_PACKET = 0x20;
|
||||
const MOB_ARMOR_EQUIPMENT_PACKET = 0x21;
|
||||
const INTERACT_PACKET = 0x22;
|
||||
const USE_ITEM_PACKET = 0x23;
|
||||
const PLAYER_ACTION_PACKET = 0x24;
|
||||
const HURT_ARMOR_PACKET = 0x25;
|
||||
const SET_ENTITY_DATA_PACKET = 0x26;
|
||||
const SET_ENTITY_MOTION_PACKET = 0x27;
|
||||
const SET_ENTITY_LINK_PACKET = 0x28;
|
||||
const SET_HEALTH_PACKET = 0x29;
|
||||
const SET_SPAWN_POSITION_PACKET = 0x2a;
|
||||
const ANIMATE_PACKET = 0x2b;
|
||||
const RESPAWN_PACKET = 0x2c;
|
||||
const DROP_ITEM_PACKET = 0x2d;
|
||||
const INVENTORY_ACTION_PACKET = 0x2e;
|
||||
const CONTAINER_OPEN_PACKET = 0x2f;
|
||||
const CONTAINER_CLOSE_PACKET = 0x30;
|
||||
const CONTAINER_SET_SLOT_PACKET = 0x31;
|
||||
const CONTAINER_SET_DATA_PACKET = 0x32;
|
||||
const CONTAINER_SET_CONTENT_PACKET = 0x33;
|
||||
const CRAFTING_DATA_PACKET = 0x34;
|
||||
const CRAFTING_EVENT_PACKET = 0x35;
|
||||
const ADVENTURE_SETTINGS_PACKET = 0x36;
|
||||
const BLOCK_ENTITY_DATA_PACKET = 0x37;
|
||||
const PLAYER_INPUT_PACKET = 0x38;
|
||||
const FULL_CHUNK_DATA_PACKET = 0x39;
|
||||
const SET_COMMANDS_ENABLED_PACKET = 0x3a;
|
||||
const SET_DIFFICULTY_PACKET = 0x3b;
|
||||
const CHANGE_DIMENSION_PACKET = 0x3c;
|
||||
const SET_PLAYER_GAME_TYPE_PACKET = 0x3d;
|
||||
const PLAYER_LIST_PACKET = 0x3e;
|
||||
const EVENT_PACKET = 0x3f;
|
||||
const SPAWN_EXPERIENCE_ORB_PACKET = 0x40;
|
||||
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x41;
|
||||
const MAP_INFO_REQUEST_PACKET = 0x42;
|
||||
const REQUEST_CHUNK_RADIUS_PACKET = 0x43;
|
||||
const CHUNK_RADIUS_UPDATED_PACKET = 0x44;
|
||||
const ITEM_FRAME_DROP_ITEM_PACKET = 0x45;
|
||||
const REPLACE_SELECTED_ITEM_PACKET = 0x46;
|
||||
const GAME_RULES_CHANGED_PACKET = 0x47;
|
||||
const CAMERA_PACKET = 0x48;
|
||||
const ADD_ITEM_PACKET = 0x49;
|
||||
const BOSS_EVENT_PACKET = 0x4a;
|
||||
const AVAILABLE_COMMANDS_PACKET = 0x4b;
|
||||
const COMMAND_STEP_PACKET = 0x4c;
|
||||
const RESOURCE_PACK_DATA_INFO_PACKET = 0x4d;
|
||||
const RESOURCE_PACK_CHUNK_DATA_PACKET = 0x4e;
|
||||
const RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x4f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,22 +30,20 @@ class InteractPacket extends DataPacket{
|
||||
const ACTION_RIGHT_CLICK = 1;
|
||||
const ACTION_LEFT_CLICK = 2;
|
||||
const ACTION_LEAVE_VEHICLE = 3;
|
||||
/** @deprecated Do NOT use this. This constant is misleading and will be removed in the future */
|
||||
const ACTION_JUMP = 3;
|
||||
const ACTION_MOUSEOVER = 4;
|
||||
|
||||
public $action;
|
||||
public $eid;
|
||||
public $target;
|
||||
|
||||
public function decode(){
|
||||
$this->action = $this->getByte();
|
||||
$this->target = $this->getLong();
|
||||
$this->target = $this->getEntityId();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->action);
|
||||
$this->putLong($this->target);
|
||||
$this->putEntityId($this->target);
|
||||
}
|
||||
|
||||
}
|
||||
|
40
src/pocketmine/network/protocol/InventoryActionPacket.php
Normal file
40
src/pocketmine/network/protocol/InventoryActionPacket.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class InventoryActionPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::INVENTORY_ACTION_PACKET;
|
||||
|
||||
public $unknown;
|
||||
public $item;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->putUnsignedVarInt($this->unknown);
|
||||
$this->putSlot($this->item);
|
||||
}
|
||||
}
|
44
src/pocketmine/network/protocol/ItemFrameDropItemPacket.php
Normal file
44
src/pocketmine/network/protocol/ItemFrameDropItemPacket.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class ItemFrameDropItemPacket extends DataPacket{
|
||||
|
||||
const NETWORK_ID = Info::ITEM_FRAME_DROP_ITEM_PACKET;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $item;
|
||||
|
||||
public function decode(){
|
||||
$this->getBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->item = $this->getSlot();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -23,7 +23,6 @@ namespace pocketmine\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class LevelEventPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::LEVEL_EVENT_PACKET;
|
||||
|
||||
@ -67,9 +66,9 @@ class LevelEventPacket extends DataPacket{
|
||||
const EVENT_ADD_PARTICLE_MASK = 0x4000;
|
||||
|
||||
public $evid;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $x = 0; //Weather effects don't have coordinates
|
||||
public $y = 0;
|
||||
public $z = 0;
|
||||
public $data;
|
||||
|
||||
public function decode(){
|
||||
@ -78,11 +77,9 @@ class LevelEventPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putShort($this->evid);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putInt($this->data);
|
||||
$this->putVarInt($this->evid);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->data);
|
||||
}
|
||||
|
||||
}
|
||||
|
56
src/pocketmine/network/protocol/LevelSoundEventPacket.php
Normal file
56
src/pocketmine/network/protocol/LevelSoundEventPacket.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class LevelSoundEventPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::LEVEL_SOUND_EVENT_PACKET;
|
||||
|
||||
public $sound;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $volume;
|
||||
public $pitch;
|
||||
public $unknownBool;
|
||||
public $unknownBool2;
|
||||
|
||||
public function decode(){
|
||||
$this->sound = $this->getByte();
|
||||
$this->getVector3f($this->x, $this->y, $this->z);
|
||||
$this->volume = $this->getVarInt();
|
||||
$this->pitch = $this->getVarInt();
|
||||
$this->unknownBool = $this->getBool();
|
||||
$this->unknownBool2 = $this->getBool();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->sound);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->volume);
|
||||
$this->putVarInt($this->pitch);
|
||||
$this->putBool($this->unknownBool);
|
||||
$this->putBool($this->unknownBool2);
|
||||
}
|
||||
}
|
@ -27,9 +27,11 @@ namespace pocketmine\network\protocol;
|
||||
class LoginPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::LOGIN_PACKET;
|
||||
|
||||
const EDITION_POCKET = 0;
|
||||
|
||||
public $username;
|
||||
public $protocol;
|
||||
|
||||
public $gameEdition;
|
||||
public $clientUUID;
|
||||
public $clientId;
|
||||
public $identityPublicKey;
|
||||
@ -44,7 +46,10 @@ class LoginPacket extends DataPacket{
|
||||
if($this->protocol !== Info::CURRENT_PROTOCOL){
|
||||
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);
|
||||
|
||||
|
@ -31,7 +31,7 @@ class MobArmorEquipmentPacket extends DataPacket{
|
||||
public $slots = [];
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->slots[0] = $this->getSlot();
|
||||
$this->slots[1] = $this->getSlot();
|
||||
$this->slots[2] = $this->getSlot();
|
||||
@ -40,7 +40,7 @@ class MobArmorEquipmentPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putSlot($this->slots[0]);
|
||||
$this->putSlot($this->slots[1]);
|
||||
$this->putSlot($this->slots[2]);
|
||||
|
@ -44,12 +44,12 @@ class MobEffectPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putByte($this->eventId);
|
||||
$this->putByte($this->effectId);
|
||||
$this->putByte($this->amplifier);
|
||||
$this->putByte($this->particles ? 1 : 0);
|
||||
$this->putInt($this->duration);
|
||||
$this->putVarInt($this->effectId);
|
||||
$this->putVarInt($this->amplifier);
|
||||
$this->putBool($this->particles);
|
||||
$this->putVarInt($this->duration);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,20 +31,23 @@ class MobEquipmentPacket extends DataPacket{
|
||||
public $item;
|
||||
public $slot;
|
||||
public $selectedSlot;
|
||||
public $unknownByte;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->eid = $this->getEntityId(); //EntityRuntimeID
|
||||
$this->item = $this->getSlot();
|
||||
$this->slot = $this->getByte();
|
||||
$this->selectedSlot = $this->getByte();
|
||||
$this->unknownByte = $this->getByte();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putSlot($this->item);
|
||||
$this->putByte($this->slot);
|
||||
$this->putByte($this->selectedSlot);
|
||||
$this->putByte($this->unknownByte);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,10 +36,8 @@ class MoveEntityPacket extends DataPacket{
|
||||
public $pitch;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->x = $this->getFloat();
|
||||
$this->y = $this->getFloat();
|
||||
$this->z = $this->getFloat();
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->getVector3f($this->x, $this->y, $this->z);
|
||||
$this->pitch = $this->getByte() * (360.0 / 256);
|
||||
$this->yaw = $this->getByte() * (360.0 / 256);
|
||||
$this->headYaw = $this->getByte() * (360.0 / 256);
|
||||
@ -47,10 +45,8 @@ class MoveEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putByte($this->pitch / (360.0 / 256));
|
||||
$this->putByte($this->yaw / (360.0 / 256));
|
||||
$this->putByte($this->headYaw / (360.0 / 256));
|
||||
|
@ -47,28 +47,24 @@ class MovePlayerPacket extends DataPacket{
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->x = $this->getFloat();
|
||||
$this->y = $this->getFloat();
|
||||
$this->z = $this->getFloat();
|
||||
$this->yaw = $this->getFloat();
|
||||
$this->bodyYaw = $this->getFloat();
|
||||
$this->pitch = $this->getFloat();
|
||||
$this->eid = $this->getEntityId(); //EntityRuntimeID
|
||||
$this->getVector3f($this->x, $this->y, $this->z);
|
||||
$this->pitch = $this->getLFloat();
|
||||
$this->yaw = $this->getLFloat();
|
||||
$this->bodyYaw = $this->getLFloat();
|
||||
$this->mode = $this->getByte();
|
||||
$this->onGround = $this->getByte() > 0;
|
||||
$this->onGround = $this->getBool();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putFloat($this->yaw);
|
||||
$this->putFloat($this->bodyYaw); //TODO
|
||||
$this->putFloat($this->pitch);
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putLFloat($this->pitch);
|
||||
$this->putLFloat($this->yaw);
|
||||
$this->putLFloat($this->bodyYaw); //TODO
|
||||
$this->putByte($this->mode);
|
||||
$this->putByte($this->onGround > 0);
|
||||
$this->putBool($this->onGround);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class PlayerActionPacket extends DataPacket{
|
||||
const ACTION_STOP_SPRINT = 10;
|
||||
const ACTION_START_SNEAK = 11;
|
||||
const ACTION_STOP_SNEAK = 12;
|
||||
const ACTION_DIMENSION_CHANGE = 13;
|
||||
const ACTION_DIMENSION_CHANGE = 13; //TODO: correct these
|
||||
|
||||
public $eid;
|
||||
public $action;
|
||||
@ -50,22 +50,18 @@ class PlayerActionPacket extends DataPacket{
|
||||
public $face;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->action = $this->getInt();
|
||||
$this->x = $this->getInt();
|
||||
$this->y = $this->getInt();
|
||||
$this->z = $this->getInt();
|
||||
$this->face = $this->getInt();
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->action = $this->getVarInt();
|
||||
$this->getBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->face = $this->getVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putInt($this->action);
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putInt($this->face);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putVarInt($this->action);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->face);
|
||||
}
|
||||
|
||||
}
|
||||
|
46
src/pocketmine/network/protocol/PlayerInputPacket.php
Normal file
46
src/pocketmine/network/protocol/PlayerInputPacket.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class PlayerInputPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::PLAYER_INPUT_PACKET;
|
||||
|
||||
public $motionX;
|
||||
public $motionY;
|
||||
public $unknownBool1;
|
||||
public $unknownBool2;
|
||||
|
||||
public function decode(){
|
||||
$this->motionX = $this->getLFloat();
|
||||
$this->motionY = $this->getLFloat();
|
||||
$this->unknownBool1 = $this->getBool();
|
||||
$this->unknownBool2 = $this->getBool();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ class PlayerListPacket extends DataPacket{
|
||||
const TYPE_ADD = 0;
|
||||
const TYPE_REMOVE = 1;
|
||||
|
||||
//REMOVE: UUID, ADD: UUID, entity id, name, isSlim, skin
|
||||
//REMOVE: UUID, ADD: UUID, entity id, name, skinId, skin
|
||||
/** @var array[] */
|
||||
public $entries = [];
|
||||
public $type;
|
||||
@ -47,11 +47,11 @@ class PlayerListPacket extends DataPacket{
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putByte($this->type);
|
||||
$this->putInt(count($this->entries));
|
||||
$this->putUnsignedVarInt(count($this->entries));
|
||||
foreach($this->entries as $d){
|
||||
if($this->type === self::TYPE_ADD){
|
||||
$this->putUUID($d[0]);
|
||||
$this->putLong($d[1]);
|
||||
$this->putEntityId($d[1]);
|
||||
$this->putString($d[2]);
|
||||
$this->putString($d[3]);
|
||||
$this->putString($d[4]);
|
||||
|
@ -27,16 +27,12 @@ namespace pocketmine\network\protocol;
|
||||
class RemoveBlockPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::REMOVE_BLOCK_PACKET;
|
||||
|
||||
public $eid;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getLong();
|
||||
$this->x = $this->getInt();
|
||||
$this->z = $this->getInt();
|
||||
$this->y = $this->getByte();
|
||||
$this->getBlockCoords($this->x, $this->y, $this->z);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
@ -35,7 +35,7 @@ class RemoveEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class ReplaceSelectedItemPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::REPLACE_SELECTED_ITEM_PACKET;
|
||||
|
||||
public $item;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putSlot($this->item);
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ class RequestChunkRadiusPacket extends DataPacket{
|
||||
public $radius;
|
||||
|
||||
public function decode(){
|
||||
$this->radius = $this->getInt();
|
||||
$this->radius = $this->getVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class ResourcePackClientResponsePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::RESOURCE_PACK_CLIENT_RESPONSE_PACKET;
|
||||
|
||||
public $unknownByte;
|
||||
public $unknownShort;
|
||||
|
||||
public function decode(){
|
||||
$this->unknownByte = $this->getByte();
|
||||
$this->unknownShort = $this->getShort();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
57
src/pocketmine/network/protocol/ResourcePacksInfoPacket.php
Normal file
57
src/pocketmine/network/protocol/ResourcePacksInfoPacket.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class ResourcePacksInfoPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::RESOURCE_PACKS_INFO_PACKET;
|
||||
|
||||
public $mustAccept = false; //force client to use selected resource packs
|
||||
/** @var ResourcePackInfoEntry */
|
||||
public $behaviourPackEntries = [];
|
||||
/** @var ResourcePackInfoEntry */
|
||||
public $resourcePackEntries = [];
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
|
||||
$this->putBool($this->mustAccept);
|
||||
$this->putShort(count($this->behaviourPackEntries));
|
||||
foreach($this->behaviourPackEntries as $entry){
|
||||
$this->putString($entry->getPackId());
|
||||
$this->putString($entry->getVersion());
|
||||
$this->putLong($entry->getUint64());
|
||||
}
|
||||
$this->putShort(count($this->resourcePackEntries));
|
||||
foreach($this->resourcePackEntries as $entry){
|
||||
$this->putString($entry->getPackId());
|
||||
$this->putString($entry->getVersion());
|
||||
$this->putLong($entry->getUint64());
|
||||
}
|
||||
}
|
||||
}
|
@ -32,16 +32,16 @@ class RespawnPacket extends DataPacket{
|
||||
public $z;
|
||||
|
||||
public function decode(){
|
||||
$this->x = $this->getFloat();
|
||||
$this->y = $this->getFloat();
|
||||
$this->z = $this->getFloat();
|
||||
$this->x = $this->getLFloat();
|
||||
$this->y = $this->getLFloat();
|
||||
$this->z = $this->getLFloat();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putLFloat($this->x);
|
||||
$this->putLFloat($this->y);
|
||||
$this->putLFloat($this->z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
41
src/pocketmine/network/protocol/SetCommandsEnabledPacket.php
Normal file
41
src/pocketmine/network/protocol/SetCommandsEnabledPacket.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class SetCommandsEnabledPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::SET_COMMANDS_ENABLED_PACKET;
|
||||
|
||||
public $enabled;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putBool($this->enabled);
|
||||
}
|
||||
|
||||
}
|
@ -30,12 +30,12 @@ class SetDifficultyPacket extends DataPacket{
|
||||
public $difficulty;
|
||||
|
||||
public function decode(){
|
||||
$this->difficulty = $this->getInt();
|
||||
$this->difficulty = $this->getUnsignedVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->difficulty);
|
||||
$this->putUnsignedVarInt($this->difficulty);
|
||||
}
|
||||
|
||||
}
|
@ -40,7 +40,7 @@ class SetEntityDataPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->eid);
|
||||
$meta = Binary::writeMetadata($this->metadata);
|
||||
$this->put($meta);
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ class SetEntityLinkPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->from);
|
||||
$this->putLong($this->to);
|
||||
$this->putEntityId($this->from);
|
||||
$this->putEntityId($this->to);
|
||||
$this->putByte($this->type);
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,10 @@ namespace pocketmine\network\protocol;
|
||||
class SetEntityMotionPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::SET_ENTITY_MOTION_PACKET;
|
||||
|
||||
|
||||
// eid, motX, motY, motZ
|
||||
/** @var array[] */
|
||||
public $entities = [];
|
||||
public $eid;
|
||||
public $motionX;
|
||||
public $motionY;
|
||||
public $motionZ;
|
||||
|
||||
public function clean(){
|
||||
$this->entities = [];
|
||||
@ -43,13 +43,8 @@ class SetEntityMotionPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt(count($this->entities));
|
||||
foreach($this->entities as $d){
|
||||
$this->putLong($d[0]); //eid
|
||||
$this->putFloat($d[1]); //motX
|
||||
$this->putFloat($d[2]); //motY
|
||||
$this->putFloat($d[3]); //motZ
|
||||
}
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putVector3f($this->motionX, $this->motionY, $this->motionZ);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class SetHealthPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->health);
|
||||
$this->putVarInt($this->health);
|
||||
}
|
||||
|
||||
}
|
@ -25,17 +25,17 @@ namespace pocketmine\network\protocol;
|
||||
|
||||
|
||||
class SetPlayerGameTypePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::SET_PLAYER_GAMETYPE_PACKET;
|
||||
const NETWORK_ID = Info::SET_PLAYER_GAME_TYPE_PACKET;
|
||||
|
||||
public $gamemode;
|
||||
|
||||
public function decode(){
|
||||
|
||||
$this->gamemode = $this->getVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->gamemode);
|
||||
$this->putVarInt($this->gamemode);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,9 +27,11 @@ namespace pocketmine\network\protocol;
|
||||
class SetSpawnPositionPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::SET_SPAWN_POSITION_PACKET;
|
||||
|
||||
public $unknown;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $unknownBool;
|
||||
|
||||
public function decode(){
|
||||
|
||||
@ -37,9 +39,9 @@ class SetSpawnPositionPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->x);
|
||||
$this->putInt($this->y);
|
||||
$this->putInt($this->z);
|
||||
$this->putVarInt($this->unknown);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putBool($this->unknownBool);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ class SetTimePacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->time);
|
||||
$this->putByte($this->started ? 1 : 0);
|
||||
$this->putVarInt($this->time);
|
||||
$this->putBool($this->started);
|
||||
}
|
||||
|
||||
}
|
||||
|
44
src/pocketmine/network/protocol/SpawnExperienceOrbPacket.php
Normal file
44
src/pocketmine/network/protocol/SpawnExperienceOrbPacket.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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\network\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
class SpawnExperienceOrbPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::SPAWN_EXPERIENCE_ORB_PACKET;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $amount;
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->amount);
|
||||
}
|
||||
}
|
@ -27,18 +27,28 @@ namespace pocketmine\network\protocol;
|
||||
class StartGamePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::START_GAME_PACKET;
|
||||
|
||||
public $seed;
|
||||
public $dimension;
|
||||
public $generator;
|
||||
public $gamemode;
|
||||
public $eid;
|
||||
public $spawnX;
|
||||
public $spawnY;
|
||||
public $spawnZ;
|
||||
public $entityUniqueId;
|
||||
public $entityRuntimeId;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $unknown;
|
||||
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 $hasAchievementsDisabled = 1;
|
||||
public $dayCycleStopTime = -1; //-1 = not stopped, any positive value = stopped at that time
|
||||
public $eduMode = 0;
|
||||
public $rainLevel;
|
||||
public $lightningLevel;
|
||||
public $commandsEnabled;
|
||||
public $isTexturePacksRequired = 0;
|
||||
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
|
||||
public $worldName;
|
||||
|
||||
public function decode(){
|
||||
|
||||
@ -46,21 +56,26 @@ class StartGamePacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putInt($this->seed);
|
||||
$this->putByte($this->dimension);
|
||||
$this->putInt($this->generator);
|
||||
$this->putInt($this->gamemode);
|
||||
$this->putLong($this->eid);
|
||||
$this->putInt($this->spawnX);
|
||||
$this->putInt($this->spawnY);
|
||||
$this->putInt($this->spawnZ);
|
||||
$this->putFloat($this->x);
|
||||
$this->putFloat($this->y);
|
||||
$this->putFloat($this->z);
|
||||
$this->putByte(1);
|
||||
$this->putByte(1);
|
||||
$this->putByte(0);
|
||||
$this->putString($this->unknown);
|
||||
$this->putEntityId($this->entityUniqueId); //EntityUniqueID
|
||||
$this->putEntityId($this->entityRuntimeId); //EntityRuntimeID
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putLFloat(0); //TODO: find out what these are (yaw/pitch?)
|
||||
$this->putLFloat(0);
|
||||
$this->putVarInt($this->seed);
|
||||
$this->putVarInt($this->dimension);
|
||||
$this->putVarInt($this->generator);
|
||||
$this->putVarInt($this->gamemode);
|
||||
$this->putVarInt($this->difficulty);
|
||||
$this->putBlockCoords($this->spawnX, $this->spawnY, $this->spawnZ);
|
||||
$this->putBool($this->hasAchievementsDisabled);
|
||||
$this->putVarInt($this->dayCycleStopTime);
|
||||
$this->putBool($this->eduMode);
|
||||
$this->putLFloat($this->rainLevel);
|
||||
$this->putLFloat($this->lightningLevel);
|
||||
$this->putBool($this->commandsEnabled);
|
||||
$this->putBool($this->isTexturePacksRequired);
|
||||
$this->putString($this->levelId);
|
||||
$this->putString($this->worldName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ class TakeItemEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->target);
|
||||
$this->putLong($this->eid);
|
||||
$this->putEntityId($this->target);
|
||||
$this->putEntityId($this->eid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class TextPacket extends DataPacket{
|
||||
const TYPE_POPUP = 3;
|
||||
const TYPE_TIP = 4;
|
||||
const TYPE_SYSTEM = 5;
|
||||
const TYPE_WHISPER = 6;
|
||||
|
||||
public $type;
|
||||
public $source;
|
||||
|
@ -40,15 +40,13 @@ class UpdateAttributesPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
|
||||
$this->putLong($this->entityId);
|
||||
|
||||
$this->putShort(count($this->entries));
|
||||
|
||||
$this->putEntityId($this->entityId);
|
||||
$this->putUnsignedVarInt(count($this->entries));
|
||||
foreach($this->entries as $entry){
|
||||
$this->putFloat($entry->getMinValue());
|
||||
$this->putFloat($entry->getMaxValue());
|
||||
$this->putFloat($entry->getValue());
|
||||
$this->putLFloat($entry->getMinValue());
|
||||
$this->putLFloat($entry->getMaxValue());
|
||||
$this->putLFloat($entry->getValue());
|
||||
$this->putLFloat($entry->getDefaultValue());
|
||||
$this->putString($entry->getName());
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user