mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Merge branch 'stable' into next-minor
This commit is contained in:
commit
dbaf851be7
@ -1 +1 @@
|
||||
Subproject commit 83085714483a0cf3a13b4fa780bd14b153c5c36b
|
||||
Subproject commit 61e20ab9e39fb64514c1031e5ae6320b8129e14c
|
@ -1 +1 @@
|
||||
Subproject commit 63e0092d623d13e47f9083b3d65fdf431933a471
|
||||
Subproject commit da363df5f15e3a92817683b695455eced04992ba
|
@ -66,3 +66,16 @@ Plugin developers should **only** update their required API to this version if y
|
||||
- `ClientboundMapItemDataPacket` now uses `MapDecoration` objects for decorations instead of associative arrays.
|
||||
- Updated Composer dependencies to get bug fixes in `pocketmine/nbt` and other libraries.
|
||||
- Packages `pocketmine/classloader` and `pocketmine/log` are now required; these provide classes previously part of `pocketmine/spl`. This change has no effect on API compatibility.
|
||||
|
||||
# 3.11.6
|
||||
- Core code, tests and build scripts are now analyzed using `phpstan-strict-rules` and `phpstan-phpunit` rules.
|
||||
- Added more PHPStan-specific type annotations to improve static analysis.
|
||||
- Fixed more incorrect PHPDoc types.
|
||||
- Added a workaround for player movement not working since 1.14.30.
|
||||
- Fixed lava and water buckets being edible since 1.13.
|
||||
- `AutoUpdater` is now created before any plugins are loaded.
|
||||
- Fixed trees not generating below y=2 in custom generators.
|
||||
- Fixed crash when opening a chest improperly unpaired from its pair (destroyed, setBlock(), unloaded, etc.).
|
||||
- `ThreadManager` is now lazily initialized.
|
||||
- Removed raw NBT storage from `Item` internals. The following methods are now deprecated:
|
||||
- `Item::setCompoundTag()`
|
||||
|
19
composer.lock
generated
19
composer.lock
generated
@ -386,7 +386,7 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://gitlab.irstea.fr/pole-is/tools/phpunit-shim.git",
|
||||
"reference": "39b6155954d6caec1110a9e78582c4816ab247bc"
|
||||
"reference": "8ec63f895972681271191821a36f9081c236b993"
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
@ -408,6 +408,11 @@
|
||||
"phpunit"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"exclude-from-classmap": [
|
||||
"phpunit"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
@ -427,20 +432,20 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2020-01-09T03:20:20+00:00"
|
||||
"time": "2020-01-23T13:39:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "0.12.9",
|
||||
"version": "0.12.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "297cb2458a96ea96d5e9d6ef38f1b7305c071f32"
|
||||
"reference": "ca5f2b7cf81c6d8fba74f9576970399c5817e03b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/297cb2458a96ea96d5e9d6ef38f1b7305c071f32",
|
||||
"reference": "297cb2458a96ea96d5e9d6ef38f1b7305c071f32",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/ca5f2b7cf81c6d8fba74f9576970399c5817e03b",
|
||||
"reference": "ca5f2b7cf81c6d8fba74f9576970399c5817e03b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -466,7 +471,7 @@
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPStan - PHP Static Analysis Tool",
|
||||
"time": "2020-02-04T22:30:27+00:00"
|
||||
"time": "2020-02-16T14:00:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
|
@ -81,6 +81,7 @@ use pocketmine\item\Durable;
|
||||
use pocketmine\item\enchantment\EnchantmentInstance;
|
||||
use pocketmine\item\enchantment\MeleeWeaponEnchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\MaybeConsumable;
|
||||
use pocketmine\item\WritableBook;
|
||||
use pocketmine\item\WrittenBook;
|
||||
use pocketmine\lang\TextContainer;
|
||||
@ -2450,7 +2451,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR:
|
||||
if($this->isUsingItem()){
|
||||
$slot = $this->inventory->getItemInHand();
|
||||
if($slot instanceof Consumable){
|
||||
if($slot instanceof Consumable and !($slot instanceof MaybeConsumable and !$slot->canBeConsumed())){
|
||||
$ev = new PlayerItemConsumeEvent($this, $slot);
|
||||
if($this->hasItemCooldown($slot)){
|
||||
$ev->setCancelled();
|
||||
|
@ -31,6 +31,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
|
||||
const _VERSION_INFO_INCLUDED = true;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const BASE_VERSION = "3.11.6";
|
||||
const BASE_VERSION = "3.11.7";
|
||||
const IS_DEVELOPMENT_BUILD = true;
|
||||
const BUILD_NUMBER = 0;
|
||||
|
@ -55,7 +55,7 @@ abstract class Crops extends Flowable{
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}
|
||||
|
||||
$item->count--;
|
||||
$item->pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class Grass extends Solid{
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
$item->pop();
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
|
||||
return true;
|
||||
|
@ -72,7 +72,7 @@ class Sapling extends Flowable{
|
||||
//TODO: change log type
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
|
||||
$item->count--;
|
||||
$item->pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class Sugarcane extends Flowable{
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
$item->count--;
|
||||
$item->pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ use pocketmine\item\Durable;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\FoodSource;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\MaybeConsumable;
|
||||
use pocketmine\item\Totem;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\NBT;
|
||||
@ -50,6 +51,7 @@ use pocketmine\network\mcpe\protocol\ActorEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
@ -295,6 +297,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
public function consumeObject(Consumable $consumable) : bool{
|
||||
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($consumable instanceof FoodSource){
|
||||
if($consumable->requiresHunger() and !$this->isHungry()){
|
||||
return false;
|
||||
@ -819,6 +825,23 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastMovement(bool $teleport = false) : void{
|
||||
//TODO: workaround 1.14.30 bug: MoveActor(Absolute|Delta)Packet don't work on players anymore :(
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->entityRuntimeId = $this->getId();
|
||||
$pk->position = $this->getOffsetPosition($this);
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->headYaw = $this->yaw;
|
||||
$pk->mode = $teleport ? MovePlayerPacket::MODE_TELEPORT : MovePlayerPacket::MODE_NORMAL;
|
||||
|
||||
//we can't assume that everyone who is using our chunk wants to see this movement,
|
||||
//because this human might be a player who shouldn't be receiving his own movement.
|
||||
//this didn't matter when we were able to use MoveActorPacket because
|
||||
//the client just ignored MoveActor for itself, but it doesn't ignore MovePlayer for itself.
|
||||
$this->server->broadcastPacket($this->hasSpawned, $pk);
|
||||
}
|
||||
|
||||
public function close() : void{
|
||||
if(!$this->closed){
|
||||
if($this->inventory !== null){
|
||||
|
@ -37,6 +37,7 @@ use pocketmine\item\Consumable;
|
||||
use pocketmine\item\Durable;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\MaybeConsumable;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\math\VoxelRayTrace;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
@ -111,7 +112,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
$this->setHealth($health);
|
||||
|
||||
/** @var CompoundTag[]|ListTag|null */
|
||||
/** @var CompoundTag[]|ListTag|null $activeEffectsTag */
|
||||
$activeEffectsTag = $this->namedtag->getListTag("ActiveEffects");
|
||||
if($activeEffectsTag !== null){
|
||||
foreach($activeEffectsTag as $e){
|
||||
@ -359,6 +360,10 @@ abstract class Living extends Entity implements Damageable{
|
||||
* etc.
|
||||
*/
|
||||
public function consumeObject(Consumable $consumable) : bool{
|
||||
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($consumable->getAdditionalEffects() as $effect){
|
||||
$this->addEffect($effect);
|
||||
}
|
||||
|
@ -246,18 +246,18 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
public function canAddItem(Item $item) : bool{
|
||||
$item = clone $item;
|
||||
$count = $item->getCount();
|
||||
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
||||
$slot = $this->getItem($i);
|
||||
if($item->equals($slot)){
|
||||
if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){
|
||||
$item->setCount($item->getCount() - $diff);
|
||||
$count -= $diff;
|
||||
}
|
||||
}elseif($slot->isNull()){
|
||||
$item->setCount($item->getCount() - $this->getMaxStackSize());
|
||||
$count -= $this->getMaxStackSize();
|
||||
}
|
||||
|
||||
if($item->getCount() <= 0){
|
||||
if($count <= 0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ use pocketmine\event\player\PlayerBucketFillEvent;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Bucket extends Item implements Consumable{
|
||||
class Bucket extends Item implements MaybeConsumable{
|
||||
public function __construct(int $meta = 0){
|
||||
parent::__construct(self::BUCKET, $meta, "Bucket");
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
/**
|
||||
* Pops an item from the stack and returns it, decreasing the stack count of this item stack by one.
|
||||
*
|
||||
* @return $this
|
||||
* @return static A clone of this itemstack containing the amount of items that were removed from this stack.
|
||||
* @throws \InvalidArgumentException if trying to pop more items than are on the stack
|
||||
*/
|
||||
public function pop(int $count = 1) : Item{
|
||||
|
36
src/pocketmine/item/MaybeConsumable.php
Normal file
36
src/pocketmine/item/MaybeConsumable.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
/**
|
||||
* Items which are sometimes (but not always) consumable should implement this interface.
|
||||
*
|
||||
* Note: If implementing custom items, consider making separate items instead of using this.
|
||||
* This interface serves as a workaround for the consumability of buckets and shouldn't
|
||||
* really be used for anything else.
|
||||
*/
|
||||
interface MaybeConsumable extends Consumable{
|
||||
|
||||
public function canBeConsumed() : bool;
|
||||
}
|
@ -96,7 +96,7 @@ class PaintingItem extends Item{
|
||||
$entity = Entity::createEntity("Painting", $blockReplace->getLevel(), $nbt);
|
||||
|
||||
if($entity instanceof Entity){
|
||||
--$this->count;
|
||||
$this->pop();
|
||||
$entity->spawnToAll();
|
||||
|
||||
$player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound
|
||||
|
@ -54,7 +54,7 @@ abstract class ProjectileItem extends Item{
|
||||
$projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce()));
|
||||
}
|
||||
|
||||
$this->count--;
|
||||
$this->pop();
|
||||
|
||||
if($projectile instanceof Projectile){
|
||||
$projectileEv = new ProjectileLaunchEvent($projectile);
|
||||
|
@ -44,7 +44,7 @@ class SpawnEgg extends Item{
|
||||
$entity = Entity::createEntity($this->meta, $player->getLevel(), $nbt);
|
||||
|
||||
if($entity instanceof Entity){
|
||||
--$this->count;
|
||||
$this->pop();
|
||||
$entity->spawnToAll();
|
||||
return true;
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
private $chunksPerTick;
|
||||
/** @var bool */
|
||||
private $clearChunksOnTick;
|
||||
/** @var \SplFixedArray<Block> */
|
||||
/** @var \SplFixedArray<Block|null> */
|
||||
private $randomTickBlocks;
|
||||
|
||||
/** @var LevelTimings */
|
||||
@ -1042,7 +1042,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return \SplFixedArray<Block>
|
||||
* @phpstan-return \SplFixedArray<Block|null>
|
||||
*/
|
||||
public function getRandomTickedBlocks() : \SplFixedArray{
|
||||
return $this->randomTickBlocks;
|
||||
|
@ -548,6 +548,7 @@ class Chunk{
|
||||
*/
|
||||
public function setLightPopulated(bool $value = true){
|
||||
$this->lightPopulated = $value;
|
||||
$this->hasChanged = true;
|
||||
}
|
||||
|
||||
public function isPopulated() : bool{
|
||||
@ -559,6 +560,7 @@ class Chunk{
|
||||
*/
|
||||
public function setPopulated(bool $value = true){
|
||||
$this->terrainPopulated = $value;
|
||||
$this->hasChanged = true;
|
||||
}
|
||||
|
||||
public function isGenerated() : bool{
|
||||
@ -570,6 +572,7 @@ class Chunk{
|
||||
*/
|
||||
public function setGenerated(bool $value = true){
|
||||
$this->terrainGenerated = $value;
|
||||
$this->hasChanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,23 +98,27 @@ class PopulationTask extends AsyncTask{
|
||||
$manager->setChunk($chunk->getX(), $chunk->getZ(), $chunk);
|
||||
if(!$chunk->isGenerated()){
|
||||
$generator->generateChunk($chunk->getX(), $chunk->getZ());
|
||||
$chunk = $manager->getChunk($chunk->getX(), $chunk->getZ());
|
||||
$chunk->setGenerated();
|
||||
}
|
||||
|
||||
foreach($chunks as $c){
|
||||
foreach($chunks as $i => $c){
|
||||
$manager->setChunk($c->getX(), $c->getZ(), $c);
|
||||
if(!$c->isGenerated()){
|
||||
$generator->generateChunk($c->getX(), $c->getZ());
|
||||
$c->setGenerated();
|
||||
$chunks[$i] = $manager->getChunk($c->getX(), $c->getZ());
|
||||
$chunks[$i]->setGenerated();
|
||||
}
|
||||
}
|
||||
|
||||
$generator->populateChunk($chunk->getX(), $chunk->getZ());
|
||||
$chunk = $manager->getChunk($chunk->getX(), $chunk->getZ());
|
||||
$chunk->setPopulated();
|
||||
|
||||
$chunk->recalculateHeightMap();
|
||||
$chunk->populateSkyLight();
|
||||
$chunk->setLightPopulated();
|
||||
$chunk->setPopulated();
|
||||
|
||||
$this->chunk = $chunk->fastSerialize();
|
||||
|
||||
foreach($chunks as $i => $c){
|
||||
|
@ -100,7 +100,7 @@ class NetworkBinaryStream extends BinaryStream{
|
||||
$capeId = $this->getString();
|
||||
$fullSkinId = $this->getString();
|
||||
|
||||
return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId);
|
||||
return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,9 +123,7 @@ class NetworkBinaryStream extends BinaryStream{
|
||||
$this->putBool($skin->isPersona());
|
||||
$this->putBool($skin->isPersonaCapeOnClassic());
|
||||
$this->putString($skin->getCapeId());
|
||||
|
||||
//this has to be unique or the client will do stupid things
|
||||
$this->putString(UUID::fromRandom()->toString()); //full skin ID
|
||||
$this->putString($skin->getFullSkinId());
|
||||
}
|
||||
|
||||
private function getSkinImage() : SkinImage{
|
||||
|
@ -39,6 +39,12 @@ abstract class DataPacket extends NetworkBinaryStream{
|
||||
|
||||
public const NETWORK_ID = 0;
|
||||
|
||||
public const PID_MASK = 0x3ff; //10 bits
|
||||
|
||||
private const SUBCLIENT_ID_MASK = 0x03; //2 bits
|
||||
private const SENDER_SUBCLIENT_ID_SHIFT = 10;
|
||||
private const RECIPIENT_SUBCLIENT_ID_SHIFT = 12;
|
||||
|
||||
/** @var bool */
|
||||
public $isEncoded = false;
|
||||
/** @var CachedEncapsulatedPacket|null */
|
||||
@ -92,10 +98,13 @@ abstract class DataPacket extends NetworkBinaryStream{
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
protected function decodeHeader(){
|
||||
$pid = $this->getUnsignedVarInt();
|
||||
$header = $this->getUnsignedVarInt();
|
||||
$pid = $header & self::PID_MASK;
|
||||
if($pid !== static::NETWORK_ID){
|
||||
throw new \UnexpectedValueException("Expected " . static::NETWORK_ID . " for packet ID, got $pid");
|
||||
}
|
||||
$this->senderSubId = ($header >> self::SENDER_SUBCLIENT_ID_SHIFT) & self::SUBCLIENT_ID_MASK;
|
||||
$this->recipientSubId = ($header >> self::RECIPIENT_SUBCLIENT_ID_SHIFT) & self::SUBCLIENT_ID_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +132,11 @@ abstract class DataPacket extends NetworkBinaryStream{
|
||||
* @return void
|
||||
*/
|
||||
protected function encodeHeader(){
|
||||
$this->putUnsignedVarInt(static::NETWORK_ID);
|
||||
$this->putUnsignedVarInt(
|
||||
static::NETWORK_ID |
|
||||
($this->senderSubId << self::SENDER_SUBCLIENT_ID_SHIFT) |
|
||||
($this->recipientSubId << self::RECIPIENT_SUBCLIENT_ID_SHIFT)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,7 +196,7 @@ class PacketPool{
|
||||
*/
|
||||
public static function getPacket(string $buffer) : DataPacket{
|
||||
$offset = 0;
|
||||
$pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset));
|
||||
$pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK);
|
||||
$pk->setBuffer($buffer, $offset);
|
||||
|
||||
return $pk;
|
||||
|
@ -48,9 +48,9 @@ class UpdateTradePacket extends DataPacket{
|
||||
/** @var string */
|
||||
public $displayName;
|
||||
/** @var bool */
|
||||
public $isWilling;
|
||||
/** @var bool */
|
||||
public $isV2Trading;
|
||||
/** @var bool */
|
||||
public $isWilling;
|
||||
/** @var string */
|
||||
public $offers;
|
||||
|
||||
@ -62,8 +62,8 @@ class UpdateTradePacket extends DataPacket{
|
||||
$this->traderEid = $this->getEntityUniqueId();
|
||||
$this->playerEid = $this->getEntityUniqueId();
|
||||
$this->displayName = $this->getString();
|
||||
$this->isWilling = $this->getBool();
|
||||
$this->isV2Trading = $this->getBool();
|
||||
$this->isWilling = $this->getBool();
|
||||
$this->offers = $this->getRemaining();
|
||||
}
|
||||
|
||||
@ -75,8 +75,8 @@ class UpdateTradePacket extends DataPacket{
|
||||
$this->putEntityUniqueId($this->traderEid);
|
||||
$this->putEntityUniqueId($this->playerEid);
|
||||
$this->putString($this->displayName);
|
||||
$this->putBool($this->isWilling);
|
||||
$this->putBool($this->isV2Trading);
|
||||
$this->putBool($this->isWilling);
|
||||
$this->put($this->offers);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
class SkinData{
|
||||
|
||||
/** @var string */
|
||||
@ -47,11 +49,13 @@ class SkinData{
|
||||
private $personaCapeOnClassic;
|
||||
/** @var string */
|
||||
private $capeId;
|
||||
/** @var string */
|
||||
private $fullSkinId;
|
||||
|
||||
/**
|
||||
* @param SkinAnimation[] $animations
|
||||
*/
|
||||
public function __construct(string $skinId, string $resourcePatch, SkinImage $skinImage, array $animations = [], SkinImage $capeImage = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $personaCapeOnClassic = false, string $capeId = ""){
|
||||
public function __construct(string $skinId, string $resourcePatch, SkinImage $skinImage, array $animations = [], SkinImage $capeImage = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $personaCapeOnClassic = false, string $capeId = "", ?string $fullSkinId = null){
|
||||
$this->skinId = $skinId;
|
||||
$this->resourcePatch = $resourcePatch;
|
||||
$this->skinImage = $skinImage;
|
||||
@ -63,6 +67,8 @@ class SkinData{
|
||||
$this->persona = $persona;
|
||||
$this->personaCapeOnClassic = $personaCapeOnClassic;
|
||||
$this->capeId = $capeId;
|
||||
//this has to be unique or the client will do stupid things
|
||||
$this->fullSkinId = $fullSkinId ?? UUID::fromRandom()->toString();
|
||||
}
|
||||
|
||||
public function getSkinId() : string{
|
||||
@ -112,4 +118,7 @@ class SkinData{
|
||||
return $this->capeId;
|
||||
}
|
||||
|
||||
public function getFullSkinId() : string{
|
||||
return $this->fullSkinId;
|
||||
}
|
||||
}
|
||||
|
42
tests/phpunit/network/mcpe/protocol/DataPacketTest.php
Normal file
42
tests/phpunit/network/mcpe/protocol/DataPacketTest.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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DataPacketTest extends TestCase{
|
||||
|
||||
public function testHeaderFidelity() : void{
|
||||
$pk = new TestPacket();
|
||||
$pk->senderSubId = 3;
|
||||
$pk->recipientSubId = 2;
|
||||
$pk->encode();
|
||||
|
||||
$pk2 = new TestPacket();
|
||||
$pk2->setBuffer($pk->getBuffer());
|
||||
$pk2->decode();
|
||||
self::assertSame($pk2->senderSubId, 3);
|
||||
self::assertSame($pk2->recipientSubId, 2);
|
||||
}
|
||||
}
|
34
tests/phpunit/network/mcpe/protocol/TestPacket.php
Normal file
34
tests/phpunit/network/mcpe/protocol/TestPacket.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class TestPacket extends DataPacket{
|
||||
public const NETWORK_ID = 1023;
|
||||
|
||||
public function handle(NetworkSession $handler) : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user