Merge branch 'api3/network_mcpe-1.0.5' into api3/network

This commit is contained in:
Dylan K. Taylor 2017-03-26 18:52:30 +01:00
commit 07f32765ba
20 changed files with 893 additions and 227 deletions

View File

@ -114,10 +114,12 @@ use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandStepPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
@ -149,6 +151,7 @@ use pocketmine\network\mcpe\protocol\PlayerActionPacket;
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
@ -173,9 +176,11 @@ use pocketmine\network\mcpe\protocol\SetHealthPacket;
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
use pocketmine\network\mcpe\protocol\SetTimePacket;
use pocketmine\network\mcpe\protocol\SetTitlePacket;
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\StopSoundPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\mcpe\protocol\TransferPacket;
@ -1677,15 +1682,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->timings->stopTiming();
//TODO: remove this workaround (broken client MCPE 1.0.0)
if(count($this->messageQueue) > 0){
$pk = new TextPacket();
$pk->type = TextPacket::TYPE_RAW;
$pk->message = implode("\n", $this->messageQueue);
$this->dataPacket($pk);
$this->messageQueue = [];
}
return true;
}
@ -2007,6 +2003,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
case ResourcePackClientResponsePacket::STATUS_COMPLETED:
$this->completeLoginSequence();
break;
default:
return false;
}
return true;
@ -2093,10 +2091,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
public function handleMovePlayer(MovePlayerPacket $packet) : bool{
$newPos = new Vector3($packet->x, $packet->y - $this->getEyeHeight(), $packet->z);
if($newPos->distanceSquared($this) == 0 and ($packet->yaw % 360) === $this->yaw and ($packet->pitch % 360) === $this->pitch){ //player hasn't moved, just client spamming packets
return true;
}
$revert = false;
if(!$this->isAlive() or $this->spawned !== true){
$revert = true;
@ -2393,6 +2387,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return true;
}
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{
return false; //TODO
}
public function handleUseItem(UseItemPacket $packet) : bool{
if($this->spawned === false or !$this->isAlive()){
return true;
@ -3250,6 +3248,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return true;
}
public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{
return false; //TODO
}
public function handleUpdateTrade(UpdateTradePacket $packet) : bool{
return false;
}
@ -3285,6 +3287,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return false;
}
public function handlePlaySound(PlaySoundPacket $packet) : bool{
return false;
}
public function handleStopSound(StopSoundPacket $packet) : bool{
return false;
}
public function handleSetTitle(SetTitlePacket $packet) : bool{
return false;
}
public function handleUnknown(UnknownPacket $packet) : bool{
$this->server->getLogger()->debug("Received unknown packet from " . $this->getName() . ": 0x" . bin2hex($packet->payload));
return true;
@ -3371,9 +3385,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return false;
}
/** @var string[] */
private $messageQueue = [];
/**
* Sends a direct chat message to a player
*
@ -3388,14 +3399,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$message = $message->getText();
}
//TODO: Remove this workaround (broken client MCPE 1.0.0)
$this->messageQueue[] = $this->server->getLanguage()->translateString($message);
/*
$pk = new TextPacket();
$pk->type = TextPacket::TYPE_RAW;
$pk->message = $this->server->getLanguage()->translateString($message);
$this->dataPacket($pk);
*/
}
public function sendTranslation($message, array $parameters = []){

View File

@ -23,7 +23,6 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\entity\Effect;
use pocketmine\entity\InstantEffect;
use pocketmine\event\TranslationContainer;
use pocketmine\utils\TextFormat;
@ -80,12 +79,9 @@ class EffectCommand extends VanillaCommand{
$amplification = 0;
if(count($args) >= 3){
$duration = (int) $args[2];
if(!($effect instanceof InstantEffect)){
$duration *= 20;
}
}elseif($effect instanceof InstantEffect){
$duration = 1;
$duration = ((int) $args[2]) * 20; //ticks
}else{
$duration = $effect->getDefaultDuration();
}
if(count($args) >= 4){

View File

@ -28,20 +28,18 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\player\PlayerExhaustEvent;
use pocketmine\network\mcpe\protocol\MobEffectPacket;
use pocketmine\Player;
use pocketmine\utils\Config;
class Effect{
const SPEED = 1;
const SLOWNESS = 2;
const HASTE = 3;
const SWIFTNESS = 3;
const FATIGUE = 4;
const MINING_FATIGUE = 4;
const FATIGUE = 4, MINING_FATIGUE = 4;
const STRENGTH = 5;
// TODO: const HEALING = 6;
// TODO: const HARMING = 7;
const INSTANT_HEALTH = 6, HEALING = 6;
const INSTANT_DAMAGE = 7, HARMING = 7;
const JUMP = 8;
const NAUSEA = 9;
const CONFUSION = 9;
const NAUSEA = 9, CONFUSION = 9;
const REGENERATION = 10;
const DAMAGE_RESISTANCE = 11;
const FIRE_RESISTANCE = 12;
@ -54,44 +52,43 @@ class Effect{
const POISON = 19;
const WITHER = 20;
const HEALTH_BOOST = 21;
const ABSORPTION = 22; // TODO implement
const ABSORPTION = 22;
const SATURATION = 23;
const LEVITATION = 24; //TODO
/** @var Effect[] */
protected static $effects;
protected static $effects = [];
public static function init(){
self::$effects = new \SplFixedArray(256);
$config = new Config(\pocketmine\PATH . "src/pocketmine/resources/effects.json", Config::JSON, []);
self::$effects[Effect::SPEED] = new Effect(Effect::SPEED, "%potion.moveSpeed", 124, 175, 198);
self::$effects[Effect::SLOWNESS] = new Effect(Effect::SLOWNESS, "%potion.moveSlowdown", 90, 108, 129, true);
self::$effects[Effect::SWIFTNESS] = new Effect(Effect::SWIFTNESS, "%potion.digSpeed", 217, 192, 67);
self::$effects[Effect::FATIGUE] = new Effect(Effect::FATIGUE, "%potion.digSlowDown", 74, 66, 23, true);
self::$effects[Effect::STRENGTH] = new Effect(Effect::STRENGTH, "%potion.damageBoost", 147, 36, 35);
//self::$effects[Effect::HEALING] = new InstantEffect(Effect::HEALING, "%potion.heal", 248, 36, 35);
//self::$effects[Effect::HARMING] = new InstantEffect(Effect::HARMING, "%potion.harm", 67, 10, 9, true);
self::$effects[Effect::JUMP] = new Effect(Effect::JUMP, "%potion.jump", 34, 255, 76);
self::$effects[Effect::NAUSEA] = new Effect(Effect::NAUSEA, "%potion.confusion", 85, 29, 74, true);
self::$effects[Effect::REGENERATION] = new Effect(Effect::REGENERATION, "%potion.regeneration", 205, 92, 171);
self::$effects[Effect::DAMAGE_RESISTANCE] = new Effect(Effect::DAMAGE_RESISTANCE, "%potion.resistance", 153, 69, 58);
self::$effects[Effect::FIRE_RESISTANCE] = new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", 228, 154, 58);
self::$effects[Effect::WATER_BREATHING] = new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", 46, 82, 153);
self::$effects[Effect::INVISIBILITY] = new Effect(Effect::INVISIBILITY, "%potion.invisibility", 127, 131, 146);
self::$effects[Effect::BLINDNESS] = new Effect(Effect::BLINDNESS, "%potion.blindness", 191, 192, 192);
self::$effects[Effect::NIGHT_VISION] = new Effect(Effect::NIGHT_VISION, "%potion.nightVision", 0, 0, 139);
self::$effects[Effect::HUNGER] = new Effect(Effect::HUNGER, "%potion.hunger", 46, 139, 87);
self::$effects[Effect::WEAKNESS] = new Effect(Effect::WEAKNESS, "%potion.weakness", 72, 77, 72, true);
self::$effects[Effect::POISON] = new Effect(Effect::POISON, "%potion.poison", 78, 147, 49, true);
self::$effects[Effect::WITHER] = new Effect(Effect::WITHER, "%potion.wither", 53, 42, 39, true);
self::$effects[Effect::HEALTH_BOOST] = new Effect(Effect::HEALTH_BOOST, "%potion.healthBoost", 248, 125, 35);
self::$effects[Effect::ABSORPTION] = new Effect(Effect::ABSORPTION, "%potion.absorption", 36, 107, 251);
self::$effects[Effect::SATURATION] = new Effect(Effect::SATURATION, "%potion.saturation", 255, 0, 255);
foreach($config->getAll() as $name => $data){
$color = hexdec($data["color"]);
$r = ($color >> 16) & 0xff;
$g = ($color >> 8) & 0xff;
$b = $color & 0xff;
self::registerEffect($name, new Effect(
$data["id"],
"%" . $data["name"],
$r,
$g,
$b,
$data["isBad"] ?? false,
$data["default_duration"] ?? 300 * 20,
$data["has_bubbles"] ?? true
));
}
}
public static function registerEffect(string $internalName, Effect $effect){
self::$effects[$effect->getId()] = $effect;
self::$effects[$internalName] = $effect;
}
/**
* @param int $id
*
* @return $this
* @return Effect|null
*/
public static function getEffect($id){
if(isset(self::$effects[$id])){
@ -100,9 +97,14 @@ class Effect{
return null;
}
/**
* @param string $name
*
* @return Effect|null
*/
public static function getEffectByName($name){
if(defined(Effect::class . "::" . strtoupper($name))){
return self::getEffect(constant(Effect::class . "::" . strtoupper($name)));
if(isset(self::$effects[$name])){
return clone self::$effects[$name];
}
return null;
}
@ -124,40 +126,106 @@ class Effect{
protected $bad;
public function __construct($id, $name, $r, $g, $b, $isBad = false){
protected $defaultDuration = 300 * 20;
protected $hasBubbles = true;
/**
* @param int $id Effect ID as per Minecraft PE
* @param string $name Translation key used for effect name
* @param int $r 0-255, red balance of potion particle colour
* @param int $g 0-255, green balance of potion particle colour
* @param int $b 0-255, blue balance of potion particle colour
* @param bool $isBad Whether the effect is harmful
* @param int $defaultDuration Duration in ticks the effect will last for by default if applied without a duration.
* @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles)
*/
public function __construct($id, $name, $r, $g, $b, $isBad = false, int $defaultDuration = 300 * 20, bool $hasBubbles = true){
$this->id = $id;
$this->name = $name;
$this->bad = (bool) $isBad;
$this->setColor($r, $g, $b);
$this->defaultDuration = $defaultDuration;
$this->duration = $defaultDuration;
$this->hasBubbles = $hasBubbles;
}
/**
* Returns the translation key used to translate this effect's name.
* @return string
*/
public function getName(){
return $this->name;
}
/**
* Returns the effect ID as per Minecraft PE
* @return int
*/
public function getId(){
return $this->id;
}
/**
* Sets the duration in ticks of the effect.
* @param $ticks
*
* @return $this
*/
public function setDuration($ticks){
$this->duration = $ticks;
return $this;
}
/**
* Returns the duration remaining of the effect in ticks.
* @return int
*/
public function getDuration(){
return $this->duration;
}
/**
* Returns the default duration this effect will apply for if a duration is not specified.
* @return int
*/
public function getDefaultDuration() : int{
return $this->defaultDuration;
}
/**
* Returns whether this effect will give the subject potion bubbles.
* @return bool
*/
public function hasBubbles() : bool{
return $this->hasBubbles;
}
/**
* Returns whether this effect will produce some visible effect, such as bubbles or particles.
* NOTE: Do not confuse this with {@link Effect#hasBubbles}. For example, Instant Damage does not have bubbles, but still produces visible effects (particles).
*
* @return bool
*/
public function isVisible(){
return $this->show;
}
/**
* Changes the visibility of the effect.
* @param bool $bool
*
* @return $this
*/
public function setVisible($bool){
$this->show = (bool) $bool;
return $this;
}
/**
* Returns the amplifier of this effect.
* TODO: fix mess of amplifier used instead of level for effect calculation.
*
* @return int
*/
public function getAmplifier(){
@ -174,19 +242,40 @@ class Effect{
return $this;
}
/**
* Returns whether the effect is ambient.
* @return bool
*/
public function isAmbient(){
return $this->ambient;
}
/**
* Sets the ambiency of this effect.
* @param bool $ambient
*
* @return $this
*/
public function setAmbient($ambient = true){
$this->ambient = (bool) $ambient;
return $this;
}
/**
* Returns whether this effect is harmful.
* TODO: implement inverse effect results for undead mobs
*
* @return bool
*/
public function isBad(){
return $this->bad;
}
/**
* Returns whether the effect will do something on the current tick.
*
* @return bool
*/
public function canTick(){
switch($this->id){
case Effect::POISON:
@ -212,10 +301,19 @@ class Effect{
return ($this->duration % $interval) === 0;
}
return true;
case Effect::INSTANT_DAMAGE:
case Effect::INSTANT_HEALTH:
//If forced to last longer than 1 tick, these apply every tick.
return true;
}
return false;
}
/**
* Applies effect results to an entity.
*
* @param Entity $entity
*/
public function applyEffect(Entity $entity){
switch($this->id){
case Effect::POISON:
@ -241,17 +339,48 @@ class Effect{
if($entity instanceof Human){
$entity->exhaust(0.5 * $this->amplifier, PlayerExhaustEvent::CAUSE_POTION);
}
break;
case Effect::INSTANT_HEALTH:
//TODO: add particles (witch spell)
if($entity->getHealth() < $entity->getMaxHealth()){
$amount = 2 * (2 ** (($this->amplifier + 1) % 32));
$entity->heal($amount, new EntityRegainHealthEvent($entity, $amount, EntityRegainHealthEvent::CAUSE_MAGIC));
}
break;
case Effect::INSTANT_DAMAGE:
//TODO: add particles (witch spell)
$amount = 2 * (2 ** (($this->amplifier + 1) % 32));
$entity->attack($amount, new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, $amount));
break;
}
}
/**
* Returns an RGB color array of this effect's color.
* @return array
*/
public function getColor(){
return [$this->color >> 16, ($this->color >> 8) & 0xff, $this->color & 0xff];
}
/**
* Sets the color of this effect.
*
* @param int $r
* @param int $g
* @param int $b
*/
public function setColor($r, $g, $b){
$this->color = (($r & 0xff) << 16) + (($g & 0xff) << 8) + ($b & 0xff);
}
/**
* Adds this effect to the Entity, performing effect overriding as specified.
*
* @param Entity $entity
* @param bool $modify
* @param Effect|null $oldEffect
*/
public function add(Entity $entity, $modify = false, Effect $oldEffect = null){
$entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectAddEvent($entity, $this, $modify, $oldEffect));
if($ev->isCancelled()){
@ -273,30 +402,62 @@ class Effect{
$entity->dataPacket($pk);
}
if($this->id === Effect::INVISIBILITY){
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true);
$entity->setNameTagVisible(false);
}elseif($this->id === Effect::SPEED){
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
if($ev->willModify() and $oldEffect !== null){
$speed = $attr->getValue() / (1 + 0.2 * $oldEffect->getAmplifier());
}else{
$speed = $attr->getValue();
}
$speed *= (1 + 0.2 * $this->amplifier);
$attr->setValue($speed);
}elseif($this->id === Effect::SLOWNESS){
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
if($ev->willModify() and $oldEffect !== null){
$speed = $attr->getValue() / (1 - 0.15 * $oldEffect->getAmplifier());
}else{
$speed = $attr->getValue();
}
$speed *= (1 - 0.15 * $this->amplifier);
$attr->setValue($speed, true);
switch($this->id){
case Effect::INVISIBILITY:
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true);
$entity->setNameTagVisible(false);
break;
case Effect::SPEED:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
if($ev->willModify() and $oldEffect !== null){
$speed = $attr->getValue() / (1 + 0.2 * $oldEffect->getAmplifier());
}else{
$speed = $attr->getValue();
}
$speed *= (1 + 0.2 * $this->amplifier);
$attr->setValue($speed);
break;
case Effect::SLOWNESS:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
if($ev->willModify() and $oldEffect !== null){
$speed = $attr->getValue() / (1 - 0.15 * $oldEffect->getAmplifier());
}else{
$speed = $attr->getValue();
}
$speed *= (1 - 0.15 * $this->amplifier);
$attr->setValue($speed, true);
break;
case Effect::HEALTH_BOOST:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::HEALTH);
if($ev->willModify() and $oldEffect !== null){
$max = $attr->getMaxValue() - (4 * ($oldEffect->getAmplifier() + 1));
}else{
$max = $attr->getMaxValue();
}
$max += (4 * ($this->amplifier + 1));
$attr->setMaxValue($max);
break;
case Effect::ABSORPTION:
if($ev->willModify() and $oldEffect !== null){
$value = $entity->getAbsorption() - (4 * ($oldEffect->getAmplifier() + 1));
}else{
$value = $entity->getAbsorption();
}
$value += (4 * ($this->amplifier + 1));
$entity->setAbsorption($value);
break;
}
}
/**
* Removes the effect from the entity, resetting any changed values back to their original defaults.
*
* @param Entity $entity
*/
public function remove(Entity $entity){
$entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectRemoveEvent($entity, $this));
if($ev->isCancelled()){
@ -311,15 +472,26 @@ class Effect{
$entity->dataPacket($pk);
}
if($this->id === Effect::INVISIBILITY){
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
$entity->setNameTagVisible(true);
}elseif($this->id === Effect::SPEED){
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
$attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier));
}elseif($this->id === Effect::SLOWNESS){
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
$attr->setValue($attr->getValue() / (1 - 0.15 * $this->amplifier));
switch($this->id){
case Effect::INVISIBILITY:
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
$entity->setNameTagVisible(true);
break;
case Effect::SPEED:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
$attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier));
break;
case Effect::SLOWNESS:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
$attr->setValue($attr->getValue() / (1 - 0.15 * $this->amplifier));
break;
case Effect::HEALTH_BOOST:
$attr = $entity->getAttributeMap()->getAttribute(Attribute::HEALTH);
$attr->setMaxValue($attr->getMaxValue() - (4 * ($this->amplifier + 1)));
break;
case Effect::ABSORPTION:
$entity->setAbsorption($entity->getAbsorption() - (4 * ($this->amplifier + 1)));
break;
}
}
}

View File

@ -484,10 +484,6 @@ abstract class Entity extends Location implements Metadatable{
$this->effects[$effect->getId()] = $effect;
$this->recalculateEffectColor();
if($effect->getId() === Effect::HEALTH_BOOST){
$this->setHealth($this->getHealth() + 4 * ($effect->getAmplifier() + 1));
}
}
protected function recalculateEffectColor(){
@ -496,7 +492,7 @@ abstract class Entity extends Location implements Metadatable{
$count = 0;
$ambient = true;
foreach($this->effects as $effect){
if($effect->isVisible()){
if($effect->isVisible() and $effect->hasBubbles()){
$c = $effect->getColor();
$color[0] += $c[0] * ($effect->getAmplifier() + 1);
$color[1] += $c[1] * ($effect->getAmplifier() + 1);
@ -739,7 +735,21 @@ abstract class Entity extends Location implements Metadatable{
$this->setLastDamageCause($source);
$this->setHealth($this->getHealth() - $source->getFinalDamage());
$damage = $source->getFinalDamage();
$absorption = $this->getAbsorption();
if($absorption > 0){
if($absorption > $damage){
//Use absorption health before normal health.
$this->setAbsorption($absorption - $damage);
$damage = 0;
}else{
$this->setAbsorption(0);
$damage -= $absorption;
}
}
$this->setHealth($this->getHealth() - $damage);
}
/**
@ -789,6 +799,14 @@ abstract class Entity extends Location implements Metadatable{
}
}
public function getAbsorption() : int{
return 0;
}
public function setAbsorption(int $absorption){
}
/**
* @param EntityDamageEvent $type
*/
@ -811,7 +829,7 @@ abstract class Entity extends Location implements Metadatable{
* @return int
*/
public function getMaxHealth(){
return $this->maxHealth + ($this->hasEffect(Effect::HEALTH_BOOST) ? 4 * ($this->getEffect(Effect::HEALTH_BOOST)->getAmplifier() + 1) : 0);
return $this->maxHealth;
}
/**

View File

@ -77,10 +77,22 @@ abstract class Living extends Entity implements Damageable{
}
}
public function getMaxHealth(){
return $this->attributeMap->getAttribute(Attribute::HEALTH)->getMaxValue();
}
public function setMaxHealth($amount){
$this->attributeMap->getAttribute(Attribute::HEALTH)->setMaxValue($amount);
}
public function getAbsorption() : int{
return (int) $this->attributeMap->getAttribute(Attribute::ABSORPTION)->getValue();
}
public function setAbsorption(int $absorption){
$this->attributeMap->getAttribute(Attribute::ABSORPTION)->setValue($absorption);
}
public function saveNBT(){
parent::saveNBT();
$this->namedtag->Health = new ShortTag("Health", $this->getHealth());

View File

@ -21,7 +21,7 @@
namespace pocketmine\inventory;
use pocketmine\network\mcpe\protocol\types\InventoryNetworkIds;
use pocketmine\network\mcpe\protocol\types\WindowTypes;
/**
* Saves all the information regarding default inventory sizes and types
@ -63,15 +63,15 @@ class InventoryType{
//TODO: move network stuff out of here
//TODO: move inventory data to json
static::$default = [
static::CHEST => new InventoryType(27, "Chest", InventoryNetworkIds::CONTAINER),
static::DOUBLE_CHEST => new InventoryType(27 + 27, "Double Chest", InventoryNetworkIds::CONTAINER),
static::PLAYER => new InventoryType(36 + 4, "Player", InventoryNetworkIds::INVENTORY), //36 CONTAINER, 4 ARMOR
static::CRAFTING => new InventoryType(5, "Crafting", InventoryNetworkIds::INVENTORY), //yes, the use of INVENTORY is intended! 4 CRAFTING slots, 1 RESULT
static::WORKBENCH => new InventoryType(10, "Crafting", InventoryNetworkIds::WORKBENCH), //9 CRAFTING slots, 1 RESULT
static::FURNACE => new InventoryType(3, "Furnace", InventoryNetworkIds::FURNACE), //2 INPUT, 1 OUTPUT
static::ENCHANT_TABLE => new InventoryType(2, "Enchant", InventoryNetworkIds::ENCHANTMENT), //1 INPUT/OUTPUT, 1 LAPIS
static::BREWING_STAND => new InventoryType(4, "Brewing", InventoryNetworkIds::BREWING_STAND), //1 INPUT, 3 POTION
static::ANVIL => new InventoryType(3, "Anvil", InventoryNetworkIds::ANVIL) //2 INPUT, 1 OUTP
static::CHEST => new InventoryType(27, "Chest", WindowTypes::CONTAINER),
static::DOUBLE_CHEST => new InventoryType(27 + 27, "Double Chest", WindowTypes::CONTAINER),
static::PLAYER => new InventoryType(36 + 4, "Player", WindowTypes::INVENTORY), //36 CONTAINER, 4 ARMOR
static::CRAFTING => new InventoryType(5, "Crafting", WindowTypes::INVENTORY), //yes, the use of INVENTORY is intended! 4 CRAFTING slots, 1 RESULT
static::WORKBENCH => new InventoryType(10, "Crafting", WindowTypes::WORKBENCH), //9 CRAFTING slots, 1 RESULT
static::FURNACE => new InventoryType(3, "Furnace", WindowTypes::FURNACE), //2 INPUT, 1 OUTPUT
static::ENCHANT_TABLE => new InventoryType(2, "Enchant", WindowTypes::ENCHANTMENT), //1 INPUT/OUTPUT, 1 LAPIS
static::BREWING_STAND => new InventoryType(4, "Brewing", WindowTypes::BREWING_STAND), //1 INPUT, 3 POTION
static::ANVIL => new InventoryType(3, "Anvil", WindowTypes::ANVIL) //2 INPUT, 1 OUTP
];
}

View File

@ -134,9 +134,6 @@ class Level implements ChunkManager, Metadatable{
/** @var Tile[] */
private $tiles = [];
private $motionToSend = [];
private $moveToSend = [];
/** @var Player[] */
private $players = [];
@ -723,35 +720,6 @@ class Level implements ChunkManager, Metadatable{
$this->checkSleep();
}
foreach($this->moveToSend as $index => $entry){
Level::getXZ($index, $chunkX, $chunkZ);
foreach($entry as $e){
$pk = new MoveEntityPacket();
$pk->eid = $e[0];
$pk->x = $e[1];
$pk->y = $e[2];
$pk->z = $e[3];
$pk->yaw = $e[4];
$pk->headYaw = $e[5];
$pk->pitch = $e[6];
$this->addChunkPacket($chunkX, $chunkZ, $pk);
}
}
$this->moveToSend = [];
foreach($this->motionToSend as $index => $entry){
Level::getXZ($index, $chunkX, $chunkZ);
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 = [];
foreach($this->chunkPackets as $index => $entries){
Level::getXZ($index, $chunkX, $chunkZ);
$chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ);
@ -1560,8 +1528,8 @@ class Level implements ChunkManager, Metadatable{
$breakTime = 0.15;
}
if($player->hasEffect(Effect::SWIFTNESS)){
$breakTime *= 1 - (0.2 * ($player->getEffect(Effect::SWIFTNESS)->getAmplifier() + 1));
if($player->hasEffect(Effect::HASTE)){
$breakTime *= 1 - (0.2 * ($player->getEffect(Effect::HASTE)->getAmplifier() + 1));
}
if($player->hasEffect(Effect::MINING_FATIGUE)){
@ -2861,16 +2829,23 @@ class Level implements ChunkManager, Metadatable{
}
public function addEntityMotion(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z){
if(!isset($this->motionToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
$this->motionToSend[$index] = [];
}
$this->motionToSend[$index][$entityId] = [$entityId, $x, $y, $z];
$pk = new SetEntityMotionPacket();
$pk->eid = $entityId;
$pk->motionX = $x;
$pk->motionY = $y;
$pk->motionZ = $z;
$this->addChunkPacket($chunkX, $chunkZ, $pk);
}
public function addEntityMovement(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z, float $yaw, float $pitch, $headYaw = null){
if(!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
$this->moveToSend[$index] = [];
}
$this->moveToSend[$index][$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch];
$pk = new MoveEntityPacket();
$pk->eid = $entityId;
$pk->x = $x;
$pk->y = $y;
$pk->z = $z;
$pk->yaw = $yaw;
$pk->pitch = $pitch;
$pk->headYaw = $headYaw ?? $yaw;
$this->addChunkPacket($chunkX, $chunkZ, $pk);
}
}

View File

@ -36,10 +36,12 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\BatchPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandStepPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
@ -70,6 +72,7 @@ use pocketmine\network\mcpe\protocol\PlayerActionPacket;
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
@ -93,9 +96,11 @@ use pocketmine\network\mcpe\protocol\SetHealthPacket;
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
use pocketmine\network\mcpe\protocol\SetTimePacket;
use pocketmine\network\mcpe\protocol\SetTitlePacket;
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\StopSoundPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\mcpe\protocol\TransferPacket;
@ -283,10 +288,12 @@ class Network{
$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::BLOCK_PICK_REQUEST_PACKET, BlockPickRequestPacket::class);
$this->registerPacket(ProtocolInfo::CHANGE_DIMENSION_PACKET, ChangeDimensionPacket::class);
$this->registerPacket(ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket::class);
$this->registerPacket(ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET, ClientboundMapItemDataPacket::class);
$this->registerPacket(ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET, ClientToServerHandshakePacket::class);
$this->registerPacket(ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET, CommandBlockUpdatePacket::class);
$this->registerPacket(ProtocolInfo::COMMAND_STEP_PACKET, CommandStepPacket::class);
$this->registerPacket(ProtocolInfo::CONTAINER_CLOSE_PACKET, ContainerClosePacket::class);
$this->registerPacket(ProtocolInfo::CONTAINER_OPEN_PACKET, ContainerOpenPacket::class);
@ -316,6 +323,7 @@ class Network{
$this->registerPacket(ProtocolInfo::PLAYER_FALL_PACKET, PlayerFallPacket::class);
$this->registerPacket(ProtocolInfo::PLAYER_INPUT_PACKET, PlayerInputPacket::class);
$this->registerPacket(ProtocolInfo::PLAYER_LIST_PACKET, PlayerListPacket::class);
$this->registerPacket(ProtocolInfo::PLAY_SOUND_PACKET, PlaySoundPacket::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);
@ -338,9 +346,11 @@ class Network{
$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::SET_TITLE_PACKET, SetTitlePacket::class);
$this->registerPacket(ProtocolInfo::SHOW_CREDITS_PACKET, ShowCreditsPacket::class);
$this->registerPacket(ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET, SpawnExperienceOrbPacket::class);
$this->registerPacket(ProtocolInfo::START_GAME_PACKET, StartGamePacket::class);
$this->registerPacket(ProtocolInfo::STOP_SOUND_PACKET, StopSoundPacket::class);
$this->registerPacket(ProtocolInfo::TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket::class);
$this->registerPacket(ProtocolInfo::TEXT_PACKET, TextPacket::class);
$this->registerPacket(ProtocolInfo::TRANSFER_PACKET, TransferPacket::class);

View File

@ -34,10 +34,12 @@ use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandStepPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
@ -69,6 +71,7 @@ use pocketmine\network\mcpe\protocol\PlayerActionPacket;
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
@ -92,9 +95,11 @@ use pocketmine\network\mcpe\protocol\SetHealthPacket;
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
use pocketmine\network\mcpe\protocol\SetTimePacket;
use pocketmine\network\mcpe\protocol\SetTitlePacket;
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\StopSoundPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\mcpe\protocol\TransferPacket;
@ -180,6 +185,8 @@ interface NetworkSession{
public function handleInteract(InteractPacket $packet) : bool;
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool;
public function handleUseItem(UseItemPacket $packet) : bool;
public function handlePlayerAction(PlayerActionPacket $packet) : bool;
@ -268,6 +275,8 @@ interface NetworkSession{
public function handleCommandStep(CommandStepPacket $packet) : bool;
public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool;
public function handleUpdateTrade(UpdateTradePacket $packet) : bool;
public function handleResourcePackDataInfo(ResourcePackDataInfoPacket $packet) : bool;
@ -278,5 +287,11 @@ interface NetworkSession{
public function handleTransfer(TransferPacket $packet) : bool;
public function handlePlaySound(PlaySoundPacket $packet) : bool;
public function handleStopSound(StopSoundPacket $packet) : bool;
public function handleSetTitle(SetTitlePacket $packet) : bool;
public function handleUnknown(UnknownPacket $packet) : bool;
}

View File

@ -0,0 +1,52 @@
<?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\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class BlockPickRequestPacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET;
public $tileX;
public $tileY;
public $tileZ;
public $hotbarSlot;
public function decode(){
$this->getSignedBlockPosition($this->tileX, $this->tileY, $this->tileZ);
$this->hotbarSlot = $this->getByte();
}
public function encode(){
$this->reset();
$this->putSignedBlockPosition($this->tileX, $this->tileY, $this->tileZ);
$this->putByte($this->hotbarSlot);
}
public function handle(NetworkSession $session) : bool{
return $session->handleBlockPickRequest($this);
}
}

View File

@ -0,0 +1,93 @@
<?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\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class CommandBlockUpdatePacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET;
public $isBlock;
public $x;
public $y;
public $z;
public $commandBlockMode;
public $isRedstoneMode;
public $isConditional;
public $minecartEid;
public $command;
public $lastOutput;
public $name;
public $shouldTrackOutput;
public function decode(){
$this->isBlock = $this->getBool();
if($this->isBlock){
$this->getBlockPosition($this->x, $this->y, $this->z);
$this->commandBlockMode = $this->getUnsignedVarInt();
$this->isRedstoneMode = $this->getBool();
$this->isConditional = $this->getBool();
}else{
//Minecart with command block
$this->minecartEid = $this->getEntityRuntimeId();
}
$this->command = $this->getString();
$this->lastOutput = $this->getString();
$this->name = $this->getString();
$this->shouldTrackOutput = $this->getBool();
}
public function encode(){
$this->reset();
$this->putBool($this->isBlock);
if($this->isBlock){
$this->putBlockPosition($this->x, $this->y, $this->z);
$this->putUnsignedVarInt($this->commandBlockMode);
$this->putBool($this->isRedstoneMode);
$this->putBool($this->isConditional);
}else{
$this->putEntityRuntimeId($this->minecartEid);
}
$this->putString($this->command);
$this->putString($this->lastOutput);
$this->putString($this->name);
$this->putBool($this->shouldTrackOutput);
}
public function handle(NetworkSession $session) : bool{
return $session->handleCommandBlockUpdate($this);
}
}

View File

@ -120,17 +120,15 @@ abstract class DataPacket extends BinaryStream{
$value[2] = $item->getDamage();
break;
case Entity::DATA_TYPE_POS:
$value = [];
$value[0] = $this->getVarInt(); //x
$value[1] = $this->getVarInt(); //y (SIGNED)
$value[2] = $this->getVarInt(); //z
$value = [0, 0, 0];
$this->getSignedBlockPosition(...$value);
break;
case Entity::DATA_TYPE_LONG:
$value = $this->getVarLong();
break;
case Entity::DATA_TYPE_VECTOR3F:
$value = [0.0, 0.0, 0.0];
$this->getVector3f($value[0], $value[1], $value[2]);
$this->getVector3f(...$value);
break;
default:
$value = [];
@ -177,16 +175,14 @@ abstract class DataPacket extends BinaryStream{
break;
case Entity::DATA_TYPE_POS:
//TODO: change this implementation (use objects)
$this->putVarInt($d[1][0]); //x
$this->putVarInt($d[1][1]); //y (SIGNED)
$this->putVarInt($d[1][2]); //z
$this->putSignedBlockPosition(...$d[1]);
break;
case Entity::DATA_TYPE_LONG:
$this->putVarLong($d[1]);
break;
case Entity::DATA_TYPE_VECTOR3F:
//TODO: change this implementation (use objects)
$this->putVector3f($d[1][0], $d[1][1], $d[1][2]); //x, y, z
$this->putVector3f(...$d[1]); //x, y, z
}
}
}
@ -224,7 +220,7 @@ abstract class DataPacket extends BinaryStream{
}
/**
* Writes an block position with unsigned Y coordinate.
* Reads an block position with unsigned Y coordinate.
* @param int $x
* @param int $y 0-255
* @param int $z
@ -236,7 +232,7 @@ abstract class DataPacket extends BinaryStream{
}
/**
* Reads a block position with unsigned Y coordinate.
* Writes a block position with unsigned Y coordinate.
* @param int &$x
* @param int &$y
* @param int &$z
@ -247,6 +243,30 @@ abstract class DataPacket extends BinaryStream{
$this->putVarInt($z);
}
/**
* Reads a block position with a signed Y coordinate.
* @param int &$x
* @param int &$y
* @param int &$z
*/
public function getSignedBlockPosition(&$x, &$y, &$z){
$x = $this->getVarInt();
$y = $this->getVarInt();
$z = $this->getVarInt();
}
/**
* Writes a block position with a signed Y coordinate.
* @param int $x
* @param int $y
* @param int $z
*/
public function putSignedBlockPosition($x, $y, $z){
$this->putVarInt($x);
$this->putVarInt($y);
$this->putVarInt($z);
}
/**
* Reads a floating-point vector3 rounded to 4dp.
* @param float $x

View File

@ -43,9 +43,10 @@ class EntityEventPacket extends DataPacket{
const FISH_HOOK_TEASE = 14;
const SQUID_INK_CLOUD = 15;
const AMBIENT_SOUND = 16;
const RESPAWN = 17;
//TODO add new events
const RESPAWN = 18;
//TODO: add more events
public $eid;
public $event;

View File

@ -0,0 +1,58 @@
<?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\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class PlaySoundPacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET;
public $string1;
public $x;
public $y;
public $z;
public $float1;
public $float2;
public function decode(){
$this->string1 = $this->getString();
$this->getBlockPosition($this->x, $this->y, $this->z);
$this->float1 = $this->getLFloat();
$this->float2 = $this->getLFloat();
}
public function encode(){
$this->reset();
$this->putString($this->string1);
$this->putBlockPosition($this->x, $this->y, $this->z);
$this->putLFloat($this->float1);
$this->putLFloat($this->float2);
}
public function handle(NetworkSession $session) : bool{
return $session->handlePlaySound($this);
}
}

View File

@ -16,6 +16,7 @@
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
* This file is generated automatically, do not edit it manually.
*
*/
@ -30,9 +31,9 @@ interface ProtocolInfo{
/**
* Actual Minecraft: PE protocol version
*/
const CURRENT_PROTOCOL = 102;
const MINECRAFT_VERSION = "v1.0.4.11";
const MINECRAFT_VERSION_NETWORK = "1.0.4.11";
const CURRENT_PROTOCOL = 105;
const MINECRAFT_VERSION = "v1.0.5.0 beta";
const MINECRAFT_VERSION_NETWORK = "1.0.5.0";
const LOGIN_PACKET = 0x01;
const PLAY_STATUS_PACKET = 0x02;
@ -68,54 +69,59 @@ interface ProtocolInfo{
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 PLAYER_FALL_PACKET = 0x25;
const HURT_ARMOR_PACKET = 0x26;
const SET_ENTITY_DATA_PACKET = 0x27;
const SET_ENTITY_MOTION_PACKET = 0x28;
const SET_ENTITY_LINK_PACKET = 0x29;
const SET_HEALTH_PACKET = 0x2a;
const SET_SPAWN_POSITION_PACKET = 0x2b;
const ANIMATE_PACKET = 0x2c;
const RESPAWN_PACKET = 0x2d;
const DROP_ITEM_PACKET = 0x2e;
const INVENTORY_ACTION_PACKET = 0x2f;
const CONTAINER_OPEN_PACKET = 0x30;
const CONTAINER_CLOSE_PACKET = 0x31;
const CONTAINER_SET_SLOT_PACKET = 0x32;
const CONTAINER_SET_DATA_PACKET = 0x33;
const CONTAINER_SET_CONTENT_PACKET = 0x34;
const CRAFTING_DATA_PACKET = 0x35;
const CRAFTING_EVENT_PACKET = 0x36;
const ADVENTURE_SETTINGS_PACKET = 0x37;
const BLOCK_ENTITY_DATA_PACKET = 0x38;
const PLAYER_INPUT_PACKET = 0x39;
const FULL_CHUNK_DATA_PACKET = 0x3a;
const SET_COMMANDS_ENABLED_PACKET = 0x3b;
const SET_DIFFICULTY_PACKET = 0x3c;
const CHANGE_DIMENSION_PACKET = 0x3d;
const SET_PLAYER_GAME_TYPE_PACKET = 0x3e;
const PLAYER_LIST_PACKET = 0x3f;
const EVENT_PACKET = 0x40; //TelemetryEventPacket
const SPAWN_EXPERIENCE_ORB_PACKET = 0x41;
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x42; //MapItemDataPacket
const MAP_INFO_REQUEST_PACKET = 0x43;
const REQUEST_CHUNK_RADIUS_PACKET = 0x44;
const CHUNK_RADIUS_UPDATED_PACKET = 0x45;
const ITEM_FRAME_DROP_ITEM_PACKET = 0x46;
const REPLACE_ITEM_IN_SLOT_PACKET = 0x47; //ReplaceSelectedItemPacket
const GAME_RULES_CHANGED_PACKET = 0x48;
const CAMERA_PACKET = 0x49;
const ADD_ITEM_PACKET = 0x4a;
const BOSS_EVENT_PACKET = 0x4b;
const SHOW_CREDITS_PACKET = 0x4c;
const AVAILABLE_COMMANDS_PACKET = 0x4d;
const COMMAND_STEP_PACKET = 0x4e;
const UPDATE_TRADE_PACKET = 0x4f;
const RESOURCE_PACK_DATA_INFO_PACKET = 0x50;
const RESOURCE_PACK_CHUNK_DATA_PACKET = 0x51;
const RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x52;
const TRANSFER_PACKET = 0x53;
const BLOCK_PICK_REQUEST_PACKET = 0x23;
const USE_ITEM_PACKET = 0x24;
const PLAYER_ACTION_PACKET = 0x25;
const PLAYER_FALL_PACKET = 0x26;
const HURT_ARMOR_PACKET = 0x27;
const SET_ENTITY_DATA_PACKET = 0x28;
const SET_ENTITY_MOTION_PACKET = 0x29;
const SET_ENTITY_LINK_PACKET = 0x2a;
const SET_HEALTH_PACKET = 0x2b;
const SET_SPAWN_POSITION_PACKET = 0x2c;
const ANIMATE_PACKET = 0x2d;
const RESPAWN_PACKET = 0x2e;
const DROP_ITEM_PACKET = 0x2f;
const INVENTORY_ACTION_PACKET = 0x30;
const CONTAINER_OPEN_PACKET = 0x31;
const CONTAINER_CLOSE_PACKET = 0x32;
const CONTAINER_SET_SLOT_PACKET = 0x33;
const CONTAINER_SET_DATA_PACKET = 0x34;
const CONTAINER_SET_CONTENT_PACKET = 0x35;
const CRAFTING_DATA_PACKET = 0x36;
const CRAFTING_EVENT_PACKET = 0x37;
const ADVENTURE_SETTINGS_PACKET = 0x38;
const BLOCK_ENTITY_DATA_PACKET = 0x39;
const PLAYER_INPUT_PACKET = 0x3a;
const FULL_CHUNK_DATA_PACKET = 0x3b;
const SET_COMMANDS_ENABLED_PACKET = 0x3c;
const SET_DIFFICULTY_PACKET = 0x3d;
const CHANGE_DIMENSION_PACKET = 0x3e;
const SET_PLAYER_GAME_TYPE_PACKET = 0x3f;
const PLAYER_LIST_PACKET = 0x40;
const EVENT_PACKET = 0x41; //TelemetryEventPacket
const SPAWN_EXPERIENCE_ORB_PACKET = 0x42;
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43; //MapItemDataPacket
const MAP_INFO_REQUEST_PACKET = 0x44;
const REQUEST_CHUNK_RADIUS_PACKET = 0x45;
const CHUNK_RADIUS_UPDATED_PACKET = 0x46;
const ITEM_FRAME_DROP_ITEM_PACKET = 0x47;
const REPLACE_ITEM_IN_SLOT_PACKET = 0x48; //ReplaceSelectedItemPacket
const GAME_RULES_CHANGED_PACKET = 0x49;
const CAMERA_PACKET = 0x4a;
const ADD_ITEM_PACKET = 0x4b;
const BOSS_EVENT_PACKET = 0x4c;
const SHOW_CREDITS_PACKET = 0x4d;
const AVAILABLE_COMMANDS_PACKET = 0x4e;
const COMMAND_STEP_PACKET = 0x4f;
const COMMAND_BLOCK_UPDATE_PACKET = 0x50;
const UPDATE_TRADE_PACKET = 0x51;
const RESOURCE_PACK_DATA_INFO_PACKET = 0x52;
const RESOURCE_PACK_CHUNK_DATA_PACKET = 0x53;
const RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x54;
const TRANSFER_PACKET = 0x55;
const PLAY_SOUND_PACKET = 0x56;
const STOP_SOUND_PACKET = 0x57;
const SET_TITLE_PACKET = 0x58;
}

View File

@ -0,0 +1,66 @@
<?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\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class SetTitlePacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET;
const TYPE_CLEAR_TITLE = 0;
const TYPE_RESET_TITLE = 1;
const TYPE_SET_TITLE = 2;
const TYPE_SET_SUBTITLE = 3;
const TYPE_SET_ACTIONBAR_MESSAGE = 4;
const TYPE_SET_ANIMATION_TIMES = 5;
public $type;
public $text;
public $fadeInTime;
public $stayTime;
public $fadeOutTime;
public function decode(){
$this->type = $this->getVarInt();
$this->text = $this->getString();
$this->fadeInTime = $this->getVarInt();
$this->stayTime = $this->getVarInt();
$this->fadeOutTime = $this->getVarInt();
}
public function encode(){
$this->reset();
$this->putVarInt($this->type);
$this->putString($this->text);
$this->putVarInt($this->fadeInTime);
$this->putVarInt($this->stayTime);
$this->putVarInt($this->fadeOutTime);
}
public function handle(NetworkSession $session) : bool{
return $session->handleSetTitle($this);
}
}

View File

@ -19,8 +19,32 @@
*
*/
namespace pocketmine\entity;
class InstantEffect extends Effect{
namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class StopSoundPacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET;
public $string1;
public $stopAll;
public function decode(){
$this->string1 = $this->getString();
$this->stopAll = $this->getBool();
}
public function encode(){
$this->reset();
$this->putString($this->string1);
$this->putBool($this->stopAll);
}
public function handle(NetworkSession $session) : bool{
return $session->handleStopSound($this);
}
}

View File

@ -26,13 +26,14 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\WindowTypes;
class UpdateTradePacket extends DataPacket{
const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET;
//TODO: find fields
public $byte1;
public $byte2;
public $windowId;
public $windowType = WindowTypes::TRADING; //Mojang hardcoded this -_-
public $varint1;
public $varint2;
public $isWilling;
@ -42,8 +43,8 @@ class UpdateTradePacket extends DataPacket{
public $offers;
public function decode(){
$this->byte1 = $this->getByte();
$this->byte2 = $this->getByte();
$this->windowId = $this->getByte();
$this->windowType = $this->getByte();
$this->varint1 = $this->getVarInt();
$this->varint2 = $this->getVarInt();
$this->isWilling = $this->getBool();
@ -55,8 +56,8 @@ class UpdateTradePacket extends DataPacket{
public function encode(){
$this->reset();
$this->putByte($this->byte1);
$this->putByte($this->byte2);
$this->putByte($this->windowId);
$this->putByte($this->windowType);
$this->putVarInt($this->varint1);
$this->putVarInt($this->varint2);
$this->putBool($this->isWilling);

View File

@ -23,7 +23,7 @@
namespace pocketmine\network\mcpe\protocol\types;
interface InventoryNetworkIds{
interface WindowTypes{
const INVENTORY = -1;
const CONTAINER = 0;
@ -39,4 +39,9 @@ interface InventoryNetworkIds{
const MINECART_CHEST = 10;
const MINECART_HOPPER = 11;
const HORSE = 12;
const BEACON = 13;
const STRUCTURE_EDITOR = 14;
const TRADING = 15;
const COMMAND_BLOCK = 16;
}

View File

@ -0,0 +1,135 @@
{
"speed": {
"id": 1,
"color": "7cafc6",
"name": "potion.moveSpeed"
},
"slowness": {
"id": 2,
"color": "5a6c81",
"name": "potion.moveSlowdown",
"isBad": true
},
"haste": {
"id": 3,
"color": "d9c043",
"name": "potion.digSpeed"
},
"mining_fatigue": {
"id": 4,
"color": "4a4217",
"name": "potion.digSlowDown",
"isBad": true
},
"strength": {
"id": 5,
"color": "932423",
"name": "potion.damageBoost"
},
"instant_health": {
"id": 6,
"color": "f82423",
"name": "potion.heal",
"default_duration": 1,
"has_bubbles": false
},
"instant_damage": {
"id": 7,
"color": "430a09",
"name": "potion.harm",
"isBad": true,
"default_duration": 1,
"has_bubbles": false
},
"jump_boost": {
"id": 8,
"color": "22ff4c",
"name": "potion.jump"
},
"nausea": {
"id": 9,
"color": "551d4a",
"name": "potion.confusion",
"isBad": true
},
"regeneration": {
"id": 10,
"color": "cd5cab",
"name": "potion.regeneration"
},
"resistance": {
"id": 11,
"color": "99453a",
"name": "potion.resistance"
},
"fire_resistance": {
"id": 12,
"color": "e49a3a",
"name": "potion.fireResistance"
},
"water_breathing": {
"id": 13,
"color": "2e5299",
"name": "potion.waterBreathing"
},
"invisibility": {
"id": 14,
"color": "7f8392",
"name": "potion.invisibility"
},
"blindness": {
"id": 15,
"color": "1f1f23",
"name": "potion.blindness",
"isBad": true
},
"night_vision": {
"id": 16,
"color": "1f1fa1",
"name": "potion.nightVision"
},
"hunger": {
"id": 17,
"color": "587653",
"name": "potion.hunger",
"isBad": true
},
"weakness": {
"id": 18,
"color": "484d48",
"name": "potion.weakness",
"isBad": true
},
"poison": {
"id": 19,
"color": "4e9331",
"name": "potion.poison",
"isBad": true
},
"wither": {
"id": 20,
"color": "352a27",
"name": "potion.wither",
"isBad": true
},
"health_boost": {
"id": 21,
"color": "f87d23",
"name": "potion.healthBoost"
},
"absorption": {
"id": 22,
"color": "2552a5",
"name": "potion.absorption"
},
"saturation": {
"id": 23,
"color": "f82423",
"name": "potion.saturation"
},
"levitation": {
"id": 24,
"color": "ceffff",
"name": "potion.levitation"
}
}