From 465285b3c2a51c18f47a6db9db8d7bc73a741dab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jun 2020 12:26:17 +0100 Subject: [PATCH] do not rely on GameMode::getMagicNumber() to match protocol IDs --- src/network/mcpe/NetworkSession.php | 2 +- src/network/mcpe/convert/TypeConverter.php | 18 +++++++++++++++++- .../mcpe/handler/InGamePacketHandler.php | 3 ++- .../mcpe/handler/PreSpawnPacketHandler.php | 4 ++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cf449bf52..d53d1d86f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -684,7 +684,7 @@ class NetworkSession{ } public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ - $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->getClientFriendlyGamemode($mode))); + $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->coreGameModeToProtocol($mode))); $this->syncAdventureSettings($this->player); if(!$isRollback){ $this->invManager->syncCreative(); diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index cd0bc83c9..b421fc8c9 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -56,7 +56,7 @@ class TypeConverter{ * * @internal */ - public function getClientFriendlyGamemode(GameMode $gamemode) : int{ + public function coreGameModeToProtocol(GameMode $gamemode) : int{ switch($gamemode->id()){ case GameMode::SURVIVAL()->id(): return ProtocolGameMode::SURVIVAL; @@ -70,6 +70,22 @@ class TypeConverter{ } } + public function protocolGameModeToCore(int $gameMode) : GameMode{ + switch($gameMode){ + case ProtocolGameMode::SURVIVAL: + return GameMode::SURVIVAL(); + case ProtocolGameMode::CREATIVE: + return GameMode::CREATIVE(); + case ProtocolGameMode::ADVENTURE: + return GameMode::ADVENTURE(); + case ProtocolGameMode::CREATIVE_VIEWER: + case ProtocolGameMode::SURVIVAL_VIEWER: + return GameMode::SPECTATOR(); + default: + throw new \UnexpectedValueException("Unmapped protocol game mode $gameMode"); + } + } + public function coreItemStackToRecipeIngredient(Item $itemStack) : RecipeIngredient{ $meta = $itemStack->getMeta(); return new RecipeIngredient($itemStack->getId(), $meta === -1 ? 0x7fff : $meta, $itemStack->getCount()); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 8afb331f8..e5041ab19 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -582,7 +582,8 @@ class InGamePacketHandler extends PacketHandler{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - if($packet->gamemode !== $this->player->getGamemode()->getMagicNumber()){ + $converter = TypeConverter::getInstance(); + if(!$converter->protocolGameModeToCore($packet->gamemode)->equals($this->player->getGamemode())){ //Set this back to default. TODO: handle this properly $this->session->syncGameMode($this->player->getGamemode(), true); } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index b681b3171..007da0fb7 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -59,13 +59,13 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk = new StartGamePacket(); $pk->entityUniqueId = $this->player->getId(); $pk->entityRuntimeId = $this->player->getId(); - $pk->playerGamemode = TypeConverter::getInstance()->getClientFriendlyGamemode($this->player->getGamemode()); + $pk->playerGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode()); $pk->playerPosition = $this->player->getOffsetPosition($location); $pk->pitch = $location->pitch; $pk->yaw = $location->yaw; $pk->seed = -1; $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly - $pk->worldGamemode = TypeConverter::getInstance()->getClientFriendlyGamemode($this->server->getGamemode()); + $pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode()); $pk->difficulty = $location->getWorldNonNull()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY();