From 004880548c6d59db811bee479b700b4b1ae999ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Mar 2017 12:13:55 +0000 Subject: [PATCH 01/17] Autogenerated data for 1.0.5.0 --- .../network/mcpe/protocol/ProtocolInfo.php | 110 +++++++++--------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index b3bbb780c..3a5fa1114 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -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; } From 6f1b12b021ab4cc6d5eee6c44d0d559e4f79db66 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Mar 2017 19:54:03 +0000 Subject: [PATCH 02/17] Added new 1.0.5 packets --- src/pocketmine/Player.php | 25 +++++ src/pocketmine/network/Network.php | 10 ++ .../network/mcpe/NetworkSession.php | 15 +++ .../mcpe/protocol/BlockPickRequestPacket.php | 52 +++++++++++ .../protocol/CommandBlockUpdatePacket.php | 92 +++++++++++++++++++ .../network/mcpe/protocol/DataPacket.php | 42 ++++++--- .../network/mcpe/protocol/PlaySoundPacket.php | 58 ++++++++++++ .../network/mcpe/protocol/SetTitlePacket.php | 66 +++++++++++++ .../network/mcpe/protocol/StopSoundPacket.php | 50 ++++++++++ 9 files changed, 399 insertions(+), 11 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/SetTitlePacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/StopSoundPacket.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 28d0b8317..ef44d72e6 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -115,10 +115,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; @@ -150,6 +152,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; @@ -174,9 +177,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; @@ -2452,6 +2457,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; @@ -3304,6 +3313,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; } @@ -3339,6 +3352,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; diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 49e00b370..abe41caba 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -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; @@ -56,6 +58,7 @@ use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\network\mcpe\protocol\HurtArmorPacket; use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; +use pocketmine\network\mcpe\protocol\PlaySoundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryActionPacket; @@ -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; @@ -320,10 +325,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); @@ -353,6 +360,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); @@ -375,9 +383,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); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index ae790ae9e..a0c0ecfc3 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -35,10 +35,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; @@ -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; @@ -174,6 +179,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; @@ -262,6 +269,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; @@ -272,5 +281,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; } \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php new file mode 100644 index 000000000..89ff5180f --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php @@ -0,0 +1,52 @@ + + + +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); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php new file mode 100644 index 000000000..f99720e5f --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -0,0 +1,92 @@ + + + +use pocketmine\network\mcpe\NetworkSession; + +class CommandBlockUpdatePacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; + + public $isCommandBlockUpdate; + + public $x; + public $y; + public $z; + public $commandBlockMode; + public $isRedstoneMode; + public $isConditional; + + public $eid; + + public $command; + public $lastOutput; + public $name; + + public $shouldTrackOutput; + + public function decode(){ + $this->isCommandBlockUpdate = $this->getBool(); + + if($this->isCommandBlockUpdate){ + $this->getBlockPosition($this->x, $this->y, $this->z); + $this->commandBlockMode = $this->getUnsignedVarInt(); + $this->isRedstoneMode = $this->getBool(); + $this->isConditional = $this->getBool(); + }else{ + $this->eid = $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->isCommandBlockUpdate); + + if($this->isCommandBlockUpdate){ + $this->putBlockPosition($this->x, $this->y, $this->z); + $this->putUnsignedVarInt($this->commandBlockMode); + $this->putBool($this->isRedstoneMode); + $this->putBool($this->isConditional); + }else{ + $this->putEntityRuntimeId($this->eid); + } + + $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); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index d08193289..18f006290 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -116,17 +116,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 = []; @@ -173,16 +171,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 } } } @@ -220,7 +216,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 @@ -232,7 +228,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 @@ -243,6 +239,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 diff --git a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php new file mode 100644 index 000000000..ba40a6a82 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php @@ -0,0 +1,58 @@ + + + +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); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php new file mode 100644 index 000000000..3ecf312d4 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php @@ -0,0 +1,66 @@ + + + +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); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php new file mode 100644 index 000000000..a339f9121 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php @@ -0,0 +1,50 @@ + + + +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); + } +} \ No newline at end of file From f58ee2028e6f1a0eb7bf8b5a89e0ceef7c619c54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Mar 2017 19:52:57 +0000 Subject: [PATCH 03/17] Moved effects stuff to json --- src/pocketmine/entity/Effect.php | 44 ++++----- src/pocketmine/lang/locale | 2 +- src/pocketmine/resources/effects.json | 131 ++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 src/pocketmine/resources/effects.json diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index 9e95cd20b..f55c4b1de 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -28,6 +28,7 @@ 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; @@ -58,34 +59,23 @@ class Effect{ const SATURATION = 23; /** @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)); + } + } + + public static function registerEffect(string $internalName, Effect $effect){ + self::$effects[$effect->getId()] = $effect; + self::$effects[$internalName] = $effect; } /** @@ -101,8 +91,8 @@ class Effect{ } 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; } diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 8d56e216b..a1c4d8f11 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 8d56e216be03710208800ba31aa3b63612742623 +Subproject commit a1c4d8f117f27b7da42a9db644e3c252c1fc033a diff --git a/src/pocketmine/resources/effects.json b/src/pocketmine/resources/effects.json new file mode 100644 index 000000000..b750536dd --- /dev/null +++ b/src/pocketmine/resources/effects.json @@ -0,0 +1,131 @@ +{ + "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" + }, + "instant_damage": { + "id": 7, + "color": "430a09", + "name": "potion.harm", + "isBad": true + }, + "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" + } +} \ No newline at end of file From 955dc38be4b99f72ca188d7038b6519be937b7cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Mar 2017 20:06:39 +0000 Subject: [PATCH 04/17] Fixed botch-job implementation of Health Boost, will now actually work and not crash the server --- src/pocketmine/entity/Effect.php | 83 ++++++++++++++++++++------------ src/pocketmine/entity/Entity.php | 6 +-- src/pocketmine/entity/Living.php | 4 ++ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index f55c4b1de..ccbe3d109 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -263,27 +263,42 @@ 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 * ($this->amplifier + 1)); + }else{ + $max = $attr->getMaxValue(); + } + + $max += (4 * ($this->amplifier + 1)); + $attr->setMaxValue($max); + break; } } @@ -301,15 +316,23 @@ 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; } } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index e3edaccd8..3c09d906d 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -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(){ @@ -811,7 +807,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; } /** diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index e9b8d2429..b8510434f 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -77,6 +77,10 @@ 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); } From 78278a0b9343116975588b86278a6dc250409317 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Mar 2017 20:15:21 +0000 Subject: [PATCH 05/17] Fixed a mistake in old effect handling --- src/pocketmine/entity/Effect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index ccbe3d109..f901245fb 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -291,7 +291,7 @@ class Effect{ case Effect::HEALTH_BOOST: $attr = $entity->getAttributeMap()->getAttribute(Attribute::HEALTH); if($ev->willModify() and $oldEffect !== null){ - $max = $attr->getMaxValue() - (4 * ($this->amplifier + 1)); + $max = $attr->getMaxValue() - (4 * ($oldEffect->getAmplifier() + 1)); }else{ $max = $attr->getMaxValue(); } From 565335f29e4e09381989650d6c8bafba299e3c22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Mar 2017 14:24:49 -0400 Subject: [PATCH 06/17] Revert "TODO: REVERT - Added a workaround for client text duplication" This reverts commit 52748fcf64830453967fab4b43d6e823aeb37ecf. --- src/pocketmine/Player.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c1a15661b..8abf3b25b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1681,15 +1681,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; } @@ -3404,9 +3395,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; } - /** @var string[] */ - private $messageQueue = []; - /** * Sends a direct chat message to a player * @@ -3421,14 +3409,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 = []){ From e7dbda922a5e8eb4a2f7e5529c6965febdbaac8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Mar 2017 10:44:23 +0000 Subject: [PATCH 07/17] Rename some CommandBlockUpdatePacket fields --- .../mcpe/protocol/CommandBlockUpdatePacket.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php index f99720e5f..cba3f9ad0 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -30,7 +30,7 @@ use pocketmine\network\mcpe\NetworkSession; class CommandBlockUpdatePacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; - public $isCommandBlockUpdate; + public $isBlock; public $x; public $y; @@ -39,7 +39,7 @@ class CommandBlockUpdatePacket extends DataPacket{ public $isRedstoneMode; public $isConditional; - public $eid; + public $minecartEid; public $command; public $lastOutput; @@ -48,15 +48,16 @@ class CommandBlockUpdatePacket extends DataPacket{ public $shouldTrackOutput; public function decode(){ - $this->isCommandBlockUpdate = $this->getBool(); + $this->isBlock = $this->getBool(); - if($this->isCommandBlockUpdate){ + if($this->isBlock){ $this->getBlockPosition($this->x, $this->y, $this->z); $this->commandBlockMode = $this->getUnsignedVarInt(); $this->isRedstoneMode = $this->getBool(); $this->isConditional = $this->getBool(); }else{ - $this->eid = $this->getEntityRuntimeId(); + //Minecart with command block + $this->minecartEid = $this->getEntityRuntimeId(); } $this->command = $this->getString(); @@ -68,15 +69,15 @@ class CommandBlockUpdatePacket extends DataPacket{ public function encode(){ $this->reset(); - $this->putBool($this->isCommandBlockUpdate); + $this->putBool($this->isBlock); - if($this->isCommandBlockUpdate){ + 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->eid); + $this->putEntityRuntimeId($this->minecartEid); } $this->putString($this->command); From 9e341f74d867accf075bd234f791bc1c8cb43d91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Mar 2017 11:27:44 +0000 Subject: [PATCH 08/17] Added new window types and found some UpdateTradePacket fields --- .../network/mcpe/protocol/UpdateTradePacket.php | 13 +++++++------ .../mcpe/protocol/types/InventoryNetworkIds.php | 5 +++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index 8b13bb4c1..319a34e76 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -26,13 +26,14 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\types\InventoryNetworkIds; class UpdateTradePacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; //TODO: find fields - public $byte1; - public $byte2; + public $windowId; + public $windowType = InventoryNetworkIds::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); diff --git a/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php b/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php index 671010b02..be64b880c 100644 --- a/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php +++ b/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php @@ -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; + } \ No newline at end of file From c344caaf78bf834ef3cfed1ffde95d5797ea725f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Mar 2017 11:30:40 +0000 Subject: [PATCH 09/17] Refactor InventoryNetworkIds as WindowTypes --- src/pocketmine/inventory/InventoryType.php | 20 +++++++++---------- .../mcpe/protocol/UpdateTradePacket.php | 4 ++-- ...nventoryNetworkIds.php => WindowTypes.php} | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) rename src/pocketmine/network/mcpe/protocol/types/{InventoryNetworkIds.php => WindowTypes.php} (97%) diff --git a/src/pocketmine/inventory/InventoryType.php b/src/pocketmine/inventory/InventoryType.php index 86d1a3ddd..4b97db2e9 100644 --- a/src/pocketmine/inventory/InventoryType.php +++ b/src/pocketmine/inventory/InventoryType.php @@ -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 ]; } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index 319a34e76..6a8f76e2e 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -26,14 +26,14 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\types\InventoryNetworkIds; +use pocketmine\network\mcpe\protocol\types\WindowTypes; class UpdateTradePacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; //TODO: find fields public $windowId; - public $windowType = InventoryNetworkIds::TRADING; //Mojang hardcoded this -_- + public $windowType = WindowTypes::TRADING; //Mojang hardcoded this -_- public $varint1; public $varint2; public $isWilling; diff --git a/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php b/src/pocketmine/network/mcpe/protocol/types/WindowTypes.php similarity index 97% rename from src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php rename to src/pocketmine/network/mcpe/protocol/types/WindowTypes.php index be64b880c..667b69674 100644 --- a/src/pocketmine/network/mcpe/protocol/types/InventoryNetworkIds.php +++ b/src/pocketmine/network/mcpe/protocol/types/WindowTypes.php @@ -23,7 +23,7 @@ namespace pocketmine\network\mcpe\protocol\types; -interface InventoryNetworkIds{ +interface WindowTypes{ const INVENTORY = -1; const CONTAINER = 0; From 3c709b1d3e50cbfc521ed8191aeb388521e50676 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Mar 2017 15:52:00 +0000 Subject: [PATCH 10/17] Return false on unhandled/unknown resource pack client response status --- src/pocketmine/Player.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8abf3b25b..61ecff1fe 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2006,6 +2006,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade case ResourcePackClientResponsePacket::STATUS_COMPLETED: $this->processLogin(); break; + default: + return false; } return true; From 51a20470f6a1baf5659133ac2d55daf57ef9add5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Mar 2017 15:03:41 +0000 Subject: [PATCH 11/17] Switch back to the old chunk-packet method since MoveEntityPacket and SetEntityMotionPacket no longer have lists --- src/pocketmine/level/Level.php | 55 ++++++++++------------------------ 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index e16d13ad8..4441058ce 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -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); @@ -2827,16 +2795,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); } } From 4638ccbb68c398b72a6807a81c1b2a3369df07f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Mar 2017 21:58:12 +0000 Subject: [PATCH 12/17] Remove this workaround (client bug fixed in 1.0.5 beta) --- src/pocketmine/Player.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ce1823c3c..0fa8cda49 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2092,10 +2092,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; From 2d927db264bf62c926823401e653ffe3a2926bfe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Mar 2017 11:38:08 +0000 Subject: [PATCH 13/17] Implemented Instant Health and Instant Damage effects --- .../command/defaults/EffectCommand.php | 10 +- src/pocketmine/entity/Effect.php | 162 +++++++++++++++++- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/entity/InstantEffect.php | 26 --- src/pocketmine/resources/effects.json | 8 +- 5 files changed, 163 insertions(+), 45 deletions(-) delete mode 100644 src/pocketmine/entity/InstantEffect.php diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index ba30dc112..76e761b38 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -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){ diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index f901245fb..a867bda37 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -33,13 +33,11 @@ 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 HASTE = 3, SWIFTNESS = 3; + 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; @@ -69,7 +67,16 @@ class Effect{ $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)); + self::registerEffect($name, new Effect( + $data["id"], + "%" . $data["name"], + $r, + $g, + $b, + $data["isBad"] ?? false, + $data["default_duration"] ?? 300 * 20, + $data["has_bubbles"] ?? true + )); } } @@ -81,7 +88,7 @@ class Effect{ /** * @param int $id * - * @return $this + * @return Effect|null */ public static function getEffect($id){ if(isset(self::$effects[$id])){ @@ -90,6 +97,11 @@ class Effect{ return null; } + /** + * @param string $name + * + * @return Effect|null + */ public static function getEffectByName($name){ if(isset(self::$effects[$name])){ return clone self::$effects[$name]; @@ -114,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(){ @@ -164,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: @@ -202,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: @@ -231,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()){ @@ -302,6 +441,11 @@ class Effect{ } } + /** + * 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()){ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index ba1c916a5..1af903d89 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -492,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); diff --git a/src/pocketmine/entity/InstantEffect.php b/src/pocketmine/entity/InstantEffect.php deleted file mode 100644 index 708f39bee..000000000 --- a/src/pocketmine/entity/InstantEffect.php +++ /dev/null @@ -1,26 +0,0 @@ - Date: Tue, 21 Mar 2017 11:49:18 +0000 Subject: [PATCH 14/17] Updated Effect constants, removed incorrect/misleading SWIFTNESS constant So what? I'd rather crash plugins than have them suddenly behave strangely because SWIFTNESS is now an alias for SPEED instead of HASTE. --- src/pocketmine/entity/Effect.php | 6 +++--- src/pocketmine/level/Level.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index a867bda37..cf25cced1 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -33,14 +33,13 @@ use pocketmine\utils\Config; class Effect{ const SPEED = 1; const SLOWNESS = 2; - const HASTE = 3, SWIFTNESS = 3; + const HASTE = 3; const FATIGUE = 4, MINING_FATIGUE = 4; const STRENGTH = 5; 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; @@ -55,6 +54,7 @@ class Effect{ const HEALTH_BOOST = 21; const ABSORPTION = 22; // TODO implement const SATURATION = 23; + const LEVITATION = 24; //TODO /** @var Effect[] */ protected static $effects = []; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 4441058ce..50dd643b1 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1494,8 +1494,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)){ From 940b20c191b275b152e010ed2ce8b9eb807b43e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Mar 2017 13:23:57 +0000 Subject: [PATCH 15/17] Implemented Absorption effect This is a little buggy due to a client-sided bug. https://bugs.mojang.com/browse/MCPE-20520 TODO: add attribute save/restore --- src/pocketmine/entity/Effect.php | 15 +++++++++++++++ src/pocketmine/entity/Entity.php | 24 +++++++++++++++++++++++- src/pocketmine/entity/Living.php | 8 ++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index cf25cced1..a68cd8d55 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -427,6 +427,7 @@ class Effect{ $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){ @@ -438,6 +439,17 @@ class Effect{ $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; + } } @@ -477,6 +489,9 @@ class Effect{ $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; } } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 1af903d89..20de4cd3b 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -735,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); } /** @@ -785,6 +799,14 @@ abstract class Entity extends Location implements Metadatable{ } } + public function getAbsorption() : int{ + return 0; + } + + public function setAbsorption(int $absorption){ + + } + /** * @param EntityDamageEvent $type */ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index f8933d39c..fbdac34e5 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -85,6 +85,14 @@ abstract class Living extends Entity implements Damageable{ $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()); From 9a35b4fbc869824076d3738be5f74fff136f701a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Mar 2017 14:03:53 +0000 Subject: [PATCH 16/17] Removed redundant TODO comment --- src/pocketmine/entity/Effect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index a68cd8d55..49bd99525 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -52,7 +52,7 @@ 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 From 2fb92c1c623de12da8a1317b9cf2510d56fbc016 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Mar 2017 16:10:42 +0000 Subject: [PATCH 17/17] Fixed wrong constant value for EntityEventPacket::RESPAWN --- src/pocketmine/network/mcpe/protocol/EntityEventPacket.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index da6357aa7..d8d35edba 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -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;