diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a013395ca..81dc61982 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -28,10 +28,12 @@ use pocketmine\entity\Human; use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\event\player\PlayerAchievementAwardedEvent; +use pocketmine\event\player\PlayerAnimationEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDropItemEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; +use pocketmine\event\player\PlayerItemConsumeEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerLoginEvent; @@ -59,22 +61,18 @@ use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\String; use pocketmine\network\protocol\AdventureSettingsPacket; +use pocketmine\network\protocol\AnimatePacket; use pocketmine\network\protocol\ChunkDataPacket; use pocketmine\network\protocol\DataPacket; -use pocketmine\network\protocol\DisconnectPacket; +use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\Info as ProtocolInfo; use pocketmine\network\protocol\LoginStatusPacket; use pocketmine\network\protocol\MessagePacket; -use pocketmine\network\protocol\PongPacket; -use pocketmine\network\protocol\ServerHandshakePacket; use pocketmine\network\protocol\SetSpawnPositionPacket; use pocketmine\network\protocol\SetTimePacket; use pocketmine\network\protocol\StartGamePacket; use pocketmine\network\protocol\TakeItemEntityPacket; -use pocketmine\network\protocol\UnknownPacket; use pocketmine\network\protocol\UpdateBlockPacket; -use pocketmine\network\raknet\Info; -use pocketmine\network\raknet\Packet; use pocketmine\network\SourceInterface; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; @@ -744,15 +742,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } } break; - case "entity.animate": - if($data["eid"] === $this->id or $data["entity"]->getLevel() !== $this->getLevel()){ - break; - } - $pk = new AnimatePacket; - $pk->eid = $data["eid"]; - $pk->action = $data["action"]; //1 swing arm, - $this->dataPacket($pk); - break; case "entity.metadata": if($data->getID() === $this->id){ $eid = 0; @@ -1011,7 +1000,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ return; } - if(preg_match('#^[a-zA-Z0-9_]{3,16}$#', $packet->username) == 0 or $this->username === "" or $this->iusername === "rcon" or $this->iusername === "console"){ + if(preg_match('#^[a-zA-Z0-9_]{3,16}$#', $packet->username) == 0 or $this->username === "" or $this->iusername === "rcon" or $this->iusername === "console" or strlen($packet->username) > 16 or strlen($packet->username) < 3){ $this->close("", "Bad username"); return; @@ -1127,14 +1116,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->dataPacket($pk); } - //TODO: new events, or remove them! - //$this->evid[] = $this->server->event("entity.animate", array($this, "eventHandler")); - //$this->evid[] = $this->server->event("entity.event", array($this, "eventHandler")); - //$this->evid[] = $this->server->event("entity.metadata", array($this, "eventHandler")); - //$this->evid[] = $this->server->event("tile.container.slot", array($this, "eventHandler")); - //$this->evid[] = $this->server->event("tile.update", array($this, "eventHandler")); - $this->lastMeasure = microtime(true); - $this->server->getLogger()->info(TextFormat::AQUA . $this->username . TextFormat::WHITE . "[/" . $this->ip . ":" . $this->port . "] logged in with entity id " . $this->id . " at (" . $this->getLevel()->getName() . ", " . round($this->x, 4) . ", " . round($this->y, 4) . ", " . round($this->z, 4) . ")"); $this->server->getPluginManager()->callEvent(new PlayerJoinEvent($this, $this->username . " joined the game")); @@ -1322,7 +1303,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ //$this->updateMetadata(); } break; - /*case ProtocolInfo::PLAYER_ACTION_PACKET: + case ProtocolInfo::PLAYER_ACTION_PACKET: if($this->spawned === false or $this->blocked === true){ break; } @@ -1331,7 +1312,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $packet->eid = $this->id; switch($packet->action){ - case 5: //Shot arrow + /*case 5: //Shot arrow if($this->entity->inAction === true){ if($this->getSlot($this->getCurrentEquipment())->getID() === BOW){ if($this->startAction !== false){ @@ -1394,10 +1375,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->entity->inAction = false; $this->entity->updateMetadata(); break; + */ case 6: //get out of the bed $this->stopSleep(); + break; } - break;*/ + break; case ProtocolInfo::REMOVE_BLOCK_PACKET: if($this->spawned === false or $this->blocked === true){ break; @@ -1561,13 +1544,21 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } break;*/ - /*case ProtocolInfo::ANIMATE_PACKET: + case ProtocolInfo::ANIMATE_PACKET: if($this->spawned === false){ break; } - $packet->eid = $this->id; - $this->server->api->dhandle("entity.animate", array("eid" => $packet->eid, "entity" => $this->entity, "action" => $packet->action)); - break;*/ + + $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $packet->action)); + if($ev->isCancelled()){ + break; + } + + $pk = new AnimatePacket(); + $pk->eid = $this->getID(); + $pk->action = $ev->getAnimationType(); + $this->server->broadcastPacket($this->getViewers(), $pk); + break; case ProtocolInfo::RESPAWN_PACKET: if($this->spawned === false or $this->dead === false){ break; @@ -1590,16 +1581,15 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ break; case ProtocolInfo::SET_HEALTH_PACKET: //Not used break; - /*case ProtocolInfo::ENTITY_EVENT_PACKET: + case ProtocolInfo::ENTITY_EVENT_PACKET: if($this->spawned === false or $this->blocked === true){ break; } $this->craftingType = 0; - $packet->eid = $this->id; - if($this->entity->inAction === true){ - $this->entity->inAction = false; - $this->entity->updateMetadata(); + if($this->inAction === true){ + $this->inAction = false; + //$this->updateMetadata(); } switch($packet->event){ case 9: //Eating @@ -1624,26 +1614,31 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ //Item::COOKED_FISH => 5, //Item::RAW_FISH => 2, ); - $slot = $this->getSlot($this->getCurrentEquipment()); - if($this->entity->getHealth() < 20 and isset($items[$slot->getID()])){ + $slot = $this->inventory->getItemInHand(); + if($this->getHealth() < 20 and isset($items[$slot->getID()])){ + $this->server->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($this, $slot)); + if($ev->isCancelled()){ + $this->inventory->sendContents($this); + break; + } - $pk = new EntityEventPacket; + $pk = new EntityEventPacket(); $pk->eid = 0; $pk->event = 9; $this->dataPacket($pk); + $pk->eid = $this->getID(); + $this->server->broadcastPacket($this->getViewers(), $pk); - $this->entity->heal($items[$slot->getID()], "eating"); - //--$slot->count; - if($slot->getCount() <= 0){ - $this->setSlot($this->getCurrentEquipment(), Item::get(AIR, 0, 0)); - } + $this->heal($items[$slot->getID()], "eating"); + --$slot->count; + $this->inventory->setItemInHand($slot); if($slot->getID() === Item::MUSHROOM_STEW or $slot->getID() === Item::BEETROOT_SOUP){ - $this->addItem(Item::get(BOWL, 0, 1)); + $this->inventory->addItem(Item::get(Item::BOWL, 0, 1)); } } break; } - break;*/ + break; case ProtocolInfo::DROP_ITEM_PACKET: if($this->spawned === false or $this->blocked === true){ break; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 208c08fcd..b130ece02 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -30,6 +30,7 @@ use pocketmine\event\entity\EntityLevelChangeEvent; use pocketmine\event\entity\EntityMotionEvent; use pocketmine\event\entity\EntityMoveEvent; use pocketmine\event\entity\EntitySpawnEvent; +use pocketmine\event\entity\EntityTeleportEvent; use pocketmine\level\format\pmf\LevelFormat; use pocketmine\level\Level; use pocketmine\level\Position; @@ -904,6 +905,14 @@ abstract class Entity extends Position implements Metadatable{ } public function teleport(Vector3 $pos, $yaw = false, $pitch = false){ + $from = Position::fromObject($this, $this->getLevel()); + $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->getLevel()); + $this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to)); + if($ev->isCancelled()){ + return false; + } + $pos = $ev->getTo(); + $this->setMotion(new Vector3(0, 0, 0)); if($this->setPositionAndRotation($pos, $yaw === false ? $this->yaw : $yaw, $pitch === false ? $this->pitch : $pitch) !== false){ if($this instanceof Player){ diff --git a/src/pocketmine/event/entity/EntityTeleportEvent.php b/src/pocketmine/event/entity/EntityTeleportEvent.php new file mode 100644 index 000000000..322f2377e --- /dev/null +++ b/src/pocketmine/event/entity/EntityTeleportEvent.php @@ -0,0 +1,73 @@ +entity = $entity; + $this->from = $from; + $this->to = $to; + } + + /** + * @return Position + */ + public function getFrom(){ + return $this->from; + } + + /** + * @param Position $from + */ + public function setFrom(Position $from){ + $this->from = $from; + } + + /** + * @return Position + */ + public function getTo(){ + return $this->to; + } + + /** + * @param Position $to + */ + public function setTo(Position $to){ + $this->to = $to; + } + + +} \ No newline at end of file diff --git a/src/pocketmine/event/player/PlayerAnimationEvent.php b/src/pocketmine/event/player/PlayerAnimationEvent.php index 0f5cbdd73..7a9da5471 100644 --- a/src/pocketmine/event/player/PlayerAnimationEvent.php +++ b/src/pocketmine/event/player/PlayerAnimationEvent.php @@ -26,28 +26,29 @@ use pocketmine\item\Item; use pocketmine\Player; /** - * Called when a player tries to drop an item from its hotbar + * Called when a player does an animation */ -class PlayerDropItemEvent extends PlayerEvent implements Cancellable{ +class PlayerAnimationEvent extends PlayerEvent implements Cancellable{ public static $handlerList = null; - /** @var Item */ - private $drop; + const ARM_SWING = 1; + + private $animationType; /** * @param Player $player - * @param Item $drop + * @param int $animation */ - public function __construct(Player $player, Item $drop){ + public function __construct(Player $player, $animation = self::ARM_SWING){ $this->player = $player; - $this->drop = $drop; + $this->animationType = $animation; } /** - * @return Item + * @return int */ - public function getItem(){ - return $this->drop; + public function getAnimationType(){ + return $this->animationType; } } \ No newline at end of file diff --git a/src/pocketmine/network/protocol/ClientConnectPacket.php b/src/pocketmine/event/player/PlayerItemConsumeEvent.php similarity index 50% rename from src/pocketmine/network/protocol/ClientConnectPacket.php rename to src/pocketmine/event/player/PlayerItemConsumeEvent.php index 1f6ac57fd..b306230f5 100644 --- a/src/pocketmine/network/protocol/ClientConnectPacket.php +++ b/src/pocketmine/event/player/PlayerItemConsumeEvent.php @@ -2,11 +2,11 @@ /* * - * ____ _ _ __ __ _ __ __ ____ - * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ + * ____ _ _ __ __ _ __ __ ____ + * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) | - * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ - * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| + * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ + * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| * * 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 @@ -14,31 +14,40 @@ * (at your option) any later version. * * @author PocketMine Team - * @link http://www.pocketmine.net/ - * + * @link http://www.pocketmine.net/ * -*/ + * + */ -namespace pocketmine\network\protocol; +namespace pocketmine\event\player; +use pocketmine\event\Cancellable; +use pocketmine\item\Item; +use pocketmine\Player; -class ClientConnectPacket extends DataPacket{ - public $clientID; - public $session; - public $unknown1; +/** + * Called when a player eats something + */ +class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable{ + public static $handlerList = null; - public function pid(){ - return Info::CLIENT_CONNECT_PACKET; + /** @var Item */ + private $item; + + /** + * @param Player $player + * @param Item $item + */ + public function __construct(Player $player, Item $item){ + $this->player = $player; + $this->item = $item; } - public function decode(){ - $this->clientID = $this->getLong(); - $this->session = $this->getLong(); - $this->unknown1 = $this->get(1); - } - - public function encode(){ - + /** + * @return Item + */ + public function getItem(){ + return clone $this->item; } } \ No newline at end of file diff --git a/src/pocketmine/network/protocol/ClientHandshakePacket.php b/src/pocketmine/network/protocol/ClientHandshakePacket.php deleted file mode 100644 index d742986ab..000000000 --- a/src/pocketmine/network/protocol/ClientHandshakePacket.php +++ /dev/null @@ -1,54 +0,0 @@ -cookie = $this->get(4); - $this->security = $this->get(1); - $this->port = $this->getShort(true); - $this->dataArray0 = $this->get($this->getByte()); - $this->dataArray = $this->getDataArray(9); - $this->timestamp = $this->get(2); - $this->session2 = $this->getLong(); - $this->session = $this->getLong(); - } - - public function encode(){ - - } - -} \ No newline at end of file diff --git a/src/pocketmine/network/protocol/Info.php b/src/pocketmine/network/protocol/Info.php index c302fa334..7b9a32eed 100644 --- a/src/pocketmine/network/protocol/Info.php +++ b/src/pocketmine/network/protocol/Info.php @@ -25,7 +25,7 @@ namespace pocketmine\network\protocol; -abstract class Info{ +interface Info{ /** * Actual Minecraft: PE protocol version @@ -33,20 +33,6 @@ abstract class Info{ const CURRENT_PROTOCOL = 14; - const PING_PACKET = 0x00; - - const PONG_PACKET = 0x03; - - const CLIENT_CONNECT_PACKET = 0x09; - const SERVER_HANDSHAKE_PACKET = 0x10; - - const CLIENT_HANDSHAKE_PACKET = 0x13; - //const SERVER_FULL_PACKET = 0x14; - const DISCONNECT_PACKET = 0x15; - - //const BANNED_PACKET = 0x17; - - const LOGIN_PACKET = 0x82; const LOGIN_STATUS_PACKET = 0x83; const READY_PACKET = 0x84; diff --git a/src/pocketmine/network/protocol/PingPacket.php b/src/pocketmine/network/protocol/PingPacket.php deleted file mode 100644 index 6312217b2..000000000 --- a/src/pocketmine/network/protocol/PingPacket.php +++ /dev/null @@ -1,41 +0,0 @@ -time = $this->getLong(); - } - - public function encode(){ - $this->reset(); - $this->putLong($this->time); - } - -} \ No newline at end of file diff --git a/src/pocketmine/network/protocol/PongPacket.php b/src/pocketmine/network/protocol/PongPacket.php deleted file mode 100644 index 3eee77d12..000000000 --- a/src/pocketmine/network/protocol/PongPacket.php +++ /dev/null @@ -1,44 +0,0 @@ -ptime = $this->getLong(); - $this->time = $this->getLong(); - } - - public function encode(){ - $this->reset(); - $this->putLong($this->ptime); - $this->putLong($this->time); - } - -} \ No newline at end of file diff --git a/src/pocketmine/network/protocol/ServerHandshakePacket.php b/src/pocketmine/network/protocol/ServerHandshakePacket.php deleted file mode 100644 index 97fc199c3..000000000 --- a/src/pocketmine/network/protocol/ServerHandshakePacket.php +++ /dev/null @@ -1,60 +0,0 @@ -reset(); - $this->put("\x04\x3f\x57\xfe"); //cookie - $this->put("\xcd"); //Security flags - $this->putShort($this->port); - $this->putDataArray(array( - "\xf5\xff\xff\xf5", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - "\xff\xff\xff\xff", - )); - $this->put("\x00\x00"); - $this->putLong($this->session); - $this->putLong($this->session2); - } - -} \ No newline at end of file