From 6a266bcbd1937d007a82b6019596408031eb183d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 14:25:08 +0000 Subject: [PATCH] Separated XUID stuff from PlayerInfo into its own XboxLivePlayerInfo --- src/network/mcpe/NetworkSession.php | 5 +- .../mcpe/handler/LoginPacketHandler.php | 27 ++++++--- src/player/Player.php | 2 +- src/player/PlayerInfo.php | 28 +-------- src/player/XboxLivePlayerInfo.php | 59 +++++++++++++++++++ 5 files changed, 83 insertions(+), 38 deletions(-) create mode 100644 src/player/XboxLivePlayerInfo.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 60b97b209..a3b40af35 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -97,6 +97,7 @@ use pocketmine\network\NetworkSessionManager; use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; +use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; @@ -563,7 +564,7 @@ class NetworkSession{ return; } if($error === null){ - if($authenticated and $this->info->getXuid() === ""){ + if($authenticated and !($this->info instanceof XboxLivePlayerInfo)){ $error = "Expected XUID but none found"; }elseif($clientPubKey === null){ $error = "Missing client public key"; //failsafe @@ -583,7 +584,7 @@ class NetworkSession{ $this->disconnect("disconnectionScreen.notAuthenticated"); return; } - if($this->info->hasXboxData()){ + if($this->info instanceof XboxLivePlayerInfo){ $this->logger->warning("Discarding unexpected XUID for non-authenticated player"); $this->info = $this->info->withoutXboxData(); } diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index b9b072fa7..b9e81b253 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -41,6 +41,7 @@ use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; +use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\uuid\UUID; use function is_array; @@ -116,14 +117,24 @@ class LoginPacketHandler extends PacketHandler{ }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Failed to parse login UUID"); } - $playerInfo = new PlayerInfo( - $extraData->displayName, - $uuid, - $skin, - $clientData->LanguageCode, - $extraData->XUID, - (array) $clientData - ); + if($extraData->XUID !== ""){ + $playerInfo = new XboxLivePlayerInfo( + $extraData->XUID, + $extraData->displayName, + $uuid, + $skin, + $clientData->LanguageCode, + (array) $clientData + ); + }else{ + $playerInfo = new PlayerInfo( + $extraData->displayName, + $uuid, + $skin, + $clientData->LanguageCode, + (array) $clientData + ); + } ($this->playerInfoConsumer)($playerInfo); $ev = new PlayerPreLoginEvent( diff --git a/src/player/Player.php b/src/player/Player.php index a8e663c1b..ea964dfa5 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -280,7 +280,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->locale = $this->playerInfo->getLocale(); $this->uuid = $this->playerInfo->getUuid(); - $this->xuid = $this->playerInfo->getXuid(); + $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; $this->perm = new PermissibleBase($this); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index 52e9b2f7a..787042e80 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -40,8 +40,6 @@ class PlayerInfo{ private $skin; /** @var string */ private $locale; - /** @var string */ - private $xuid; /** * @var mixed[] * @phpstan-var array @@ -52,12 +50,11 @@ class PlayerInfo{ * @param mixed[] $extraData * @phpstan-param array $extraData */ - public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, array $extraData = []){ + public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; $this->locale = $locale; - $this->xuid = $xuid; $this->extraData = $extraData; } @@ -77,10 +74,6 @@ class PlayerInfo{ return $this->locale; } - public function getXuid() : string{ - return $this->xuid; - } - /** * @return mixed[] * @phpstan-return array @@ -88,23 +81,4 @@ class PlayerInfo{ public function getExtraData() : array{ return $this->extraData; } - - public function hasXboxData() : bool{ - return $this->xuid !== ""; - } - - /** - * Returns a new PlayerInfo with XBL player info stripped. This is used to ensure that non-XBL players can't spoof - * XBL data. - */ - public function withoutXboxData() : self{ - return new self( - $this->username, - $this->uuid, - $this->skin, - $this->locale, - "", - $this->extraData - ); - } } diff --git a/src/player/XboxLivePlayerInfo.php b/src/player/XboxLivePlayerInfo.php new file mode 100644 index 000000000..a0e3a2cbc --- /dev/null +++ b/src/player/XboxLivePlayerInfo.php @@ -0,0 +1,59 @@ +xuid = $xuid; + } + + public function getXuid() : string{ + return $this->xuid; + } + + /** + * Returns a new PlayerInfo with XBL player info stripped. This is used to ensure that non-XBL players can't spoof + * XBL data. + */ + public function withoutXboxData() : PlayerInfo{ + return new PlayerInfo( + $this->getUsername(), + $this->getUuid(), + $this->getSkin(), + $this->getLocale(), + $this->getExtraData() + ); + } +}