mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
LoginPacket: use netresearch/jsonmapper for login data decoding
this makes retrieval static analysis friendly without extra steps.
This commit is contained in:
parent
3e5d3a646b
commit
83a3adecff
@ -41,7 +41,8 @@
|
||||
"pocketmine/classloader": "dev-master",
|
||||
"pocketmine/callback-validator": "^1.0.1",
|
||||
"adhocore/json-comment": "^0.1.0",
|
||||
"particle/validator": "^2.3"
|
||||
"particle/validator": "^2.3",
|
||||
"netresearch/jsonmapper": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.14",
|
||||
|
48
composer.lock
generated
48
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b59b043a71525b45752770b4fd1ce2cb",
|
||||
"content-hash": "8a94ad4a1822c04cb884a6dee81923df",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -191,6 +191,52 @@
|
||||
],
|
||||
"time": "2018-12-03T18:17:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||
"reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e245890383c3ed38b6d202ee373c23ccfebc0f54",
|
||||
"reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-reflection": "*",
|
||||
"ext-spl": "*",
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0",
|
||||
"squizlabs/php_codesniffer": "~3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"JsonMapper": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"OSL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Weiske",
|
||||
"email": "cweiske@cweiske.de",
|
||||
"homepage": "http://github.com/cweiske/jsonmapper/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Map nested JSON structures onto PHP classes",
|
||||
"time": "2020-03-04T17:23:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "particle/validator",
|
||||
"version": "v2.3.4",
|
||||
|
@ -33,6 +33,7 @@ parameters:
|
||||
- pocketmine\IS_DEVELOPMENT_BUILD
|
||||
- pocketmine\DEBUG
|
||||
stubFiles:
|
||||
- tests/phpstan/stubs/JsonMapper.stub
|
||||
- tests/phpstan/stubs/pthreads.stub
|
||||
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
|
||||
ignoreErrors:
|
||||
|
@ -95,7 +95,7 @@ class ProcessLoginTask extends AsyncTask{
|
||||
$currentKey = null;
|
||||
$first = true;
|
||||
|
||||
foreach($packet->chainDataJwt as $jwt){
|
||||
foreach($packet->chainDataJwt->chain as $jwt){
|
||||
$this->validateToken($jwt, $currentKey, $first);
|
||||
if($first){
|
||||
$first = false;
|
||||
|
@ -68,38 +68,39 @@ class LoginPacketHandler extends PacketHandler{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!Player::isValidUserName($packet->extraData[LoginPacket::I_USERNAME])){
|
||||
if(!Player::isValidUserName($packet->extraData->displayName)){
|
||||
$this->session->disconnect("disconnectionScreen.invalidName");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try{
|
||||
$clientData = $packet->clientData; //this serves no purpose except readability
|
||||
/** @var SkinAnimation[] $animations */
|
||||
$animations = [];
|
||||
foreach($packet->clientData[LoginPacket::I_ANIMATION_IMAGES] as $animation){
|
||||
foreach($clientData->AnimatedImageData as $animation){
|
||||
$animations[] = new SkinAnimation(
|
||||
new SkinImage(
|
||||
$animation[LoginPacket::I_ANIMATION_IMAGE_HEIGHT],
|
||||
$animation[LoginPacket::I_ANIMATION_IMAGE_WIDTH],
|
||||
base64_decode($animation[LoginPacket::I_ANIMATION_IMAGE_DATA], true)
|
||||
$animation->ImageHeight,
|
||||
$animation->ImageWidth,
|
||||
base64_decode($animation->Image, true)
|
||||
),
|
||||
$animation[LoginPacket::I_ANIMATION_IMAGE_TYPE],
|
||||
$animation[LoginPacket::I_ANIMATION_IMAGE_FRAMES]
|
||||
$animation->Type,
|
||||
$animation->Frames
|
||||
);
|
||||
}
|
||||
$skinData = new SkinData(
|
||||
$packet->clientData[LoginPacket::I_SKIN_ID],
|
||||
base64_decode($packet->clientData[LoginPacket::I_SKIN_RESOURCE_PATCH], true),
|
||||
new SkinImage($packet->clientData[LoginPacket::I_SKIN_HEIGHT], $packet->clientData[LoginPacket::I_SKIN_WIDTH], base64_decode($packet->clientData[LoginPacket::I_SKIN_DATA], true)),
|
||||
$clientData->SkinId,
|
||||
base64_decode($clientData->SkinResourcePatch, true),
|
||||
new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, base64_decode($clientData->SkinData, true)),
|
||||
$animations,
|
||||
new SkinImage($packet->clientData[LoginPacket::I_CAPE_HEIGHT], $packet->clientData[LoginPacket::I_CAPE_WIDTH], base64_decode($packet->clientData[LoginPacket::I_CAPE_DATA], true)),
|
||||
base64_decode($packet->clientData[LoginPacket::I_GEOMETRY_DATA], true),
|
||||
base64_decode($packet->clientData[LoginPacket::I_ANIMATION_DATA], true),
|
||||
$packet->clientData[LoginPacket::I_PREMIUM_SKIN],
|
||||
$packet->clientData[LoginPacket::I_PERSONA_SKIN],
|
||||
$packet->clientData[LoginPacket::I_PERSONA_CAPE_ON_CLASSIC_SKIN],
|
||||
$packet->clientData[LoginPacket::I_CAPE_ID]
|
||||
new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, base64_decode($clientData->CapeData, true)),
|
||||
base64_decode($clientData->SkinGeometryData, true),
|
||||
base64_decode($clientData->SkinAnimationData, true),
|
||||
$clientData->PremiumSkin,
|
||||
$clientData->PersonaSkin,
|
||||
$clientData->CapeOnClassicSkin,
|
||||
$clientData->CapeId
|
||||
);
|
||||
|
||||
$skin = SkinAdapterSingleton::get()->fromSkinData($skinData);
|
||||
@ -111,12 +112,12 @@ class LoginPacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
$this->session->setPlayerInfo(new PlayerInfo(
|
||||
$packet->extraData[LoginPacket::I_USERNAME],
|
||||
UUID::fromString($packet->extraData[LoginPacket::I_UUID]),
|
||||
$packet->extraData->displayName,
|
||||
UUID::fromString($packet->extraData->identity),
|
||||
$skin,
|
||||
$packet->clientData[LoginPacket::I_LANGUAGE_CODE],
|
||||
$packet->extraData[LoginPacket::I_XUID],
|
||||
$packet->clientData
|
||||
$packet->clientData->LanguageCode,
|
||||
$packet->extraData->XUID,
|
||||
(array) $packet->clientData
|
||||
));
|
||||
|
||||
$ev = new PlayerPreLoginEvent(
|
||||
|
@ -25,77 +25,34 @@ namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use Particle\Validator\Validator;
|
||||
use pocketmine\network\BadPacketException;
|
||||
use pocketmine\network\mcpe\handler\PacketHandler;
|
||||
use pocketmine\network\mcpe\protocol\types\login\AuthenticationData;
|
||||
use pocketmine\network\mcpe\protocol\types\login\ClientData;
|
||||
use pocketmine\network\mcpe\protocol\types\login\JwtChain;
|
||||
use pocketmine\network\mcpe\serializer\NetworkBinaryStream;
|
||||
use pocketmine\utils\BinaryDataException;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\utils\Utils;
|
||||
use function array_filter;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
use function json_decode;
|
||||
use function json_last_error_msg;
|
||||
|
||||
class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET;
|
||||
|
||||
public const EDITION_POCKET = 0;
|
||||
|
||||
public const I_USERNAME = 'displayName';
|
||||
public const I_UUID = 'identity';
|
||||
public const I_XUID = 'XUID';
|
||||
|
||||
public const I_CLIENT_RANDOM_ID = 'ClientRandomId';
|
||||
public const I_SERVER_ADDRESS = 'ServerAddress';
|
||||
public const I_LANGUAGE_CODE = 'LanguageCode';
|
||||
|
||||
public const I_SKIN_RESOURCE_PATCH = 'SkinResourcePatch';
|
||||
|
||||
public const I_SKIN_ID = 'SkinId';
|
||||
public const I_SKIN_HEIGHT = 'SkinImageHeight';
|
||||
public const I_SKIN_WIDTH = 'SkinImageWidth';
|
||||
public const I_SKIN_DATA = 'SkinData';
|
||||
|
||||
public const I_CAPE_ID = 'CapeId';
|
||||
public const I_CAPE_HEIGHT = 'CapeImageHeight';
|
||||
public const I_CAPE_WIDTH = 'CapeImageWidth';
|
||||
public const I_CAPE_DATA = 'CapeData';
|
||||
|
||||
public const I_GEOMETRY_DATA = 'SkinGeometryData';
|
||||
|
||||
public const I_ANIMATION_DATA = 'SkinAnimationData';
|
||||
public const I_ANIMATION_IMAGES = 'AnimatedImageData';
|
||||
|
||||
public const I_ANIMATION_IMAGE_HEIGHT = 'ImageHeight';
|
||||
public const I_ANIMATION_IMAGE_WIDTH = 'ImageWidth';
|
||||
public const I_ANIMATION_IMAGE_FRAMES = 'Frames';
|
||||
public const I_ANIMATION_IMAGE_TYPE = 'Type';
|
||||
public const I_ANIMATION_IMAGE_DATA = 'Image';
|
||||
|
||||
public const I_PREMIUM_SKIN = 'PremiumSkin';
|
||||
public const I_PERSONA_SKIN = 'PersonaSkin';
|
||||
public const I_PERSONA_CAPE_ON_CLASSIC_SKIN = 'CapeOnClassicSkin';
|
||||
|
||||
/** @var int */
|
||||
public $protocol;
|
||||
|
||||
/** @var string[] array of encoded JWT */
|
||||
public $chainDataJwt = [];
|
||||
/**
|
||||
* @var mixed[]|null extraData index of whichever JWT has it
|
||||
* @phpstan-var array<string, mixed>
|
||||
*/
|
||||
/** @var JwtChain */
|
||||
public $chainDataJwt;
|
||||
/** @var AuthenticationData|null extraData index of whichever JWT has it */
|
||||
public $extraData = null;
|
||||
/** @var string */
|
||||
public $clientDataJwt;
|
||||
/**
|
||||
* @var mixed[] decoded payload of the clientData JWT
|
||||
* @phpstan-var array<string, mixed>
|
||||
*/
|
||||
public $clientData = [];
|
||||
/** @var ClientData decoded payload of the clientData JWT */
|
||||
public $clientData;
|
||||
|
||||
/**
|
||||
* This field may be used by plugins to bypass keychain verification. It should only be used for plugins such as
|
||||
@ -114,22 +71,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
$this->decodeConnectionRequest($in);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*
|
||||
* @throws BadPacketException
|
||||
*/
|
||||
private static function validate(Validator $v, string $name, $data) : void{
|
||||
$result = $v->validate($data);
|
||||
if($result->isNotValid()){
|
||||
$messages = [];
|
||||
foreach($result->getFailures() as $f){
|
||||
$messages[] = $f->format();
|
||||
}
|
||||
throw new BadPacketException("Failed to validate '$name': " . implode(", ", $messages));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws BadPacketException
|
||||
* @throws BinaryDataException
|
||||
@ -137,19 +78,19 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
protected function decodeConnectionRequest(NetworkBinaryStream $in) : void{
|
||||
$buffer = new BinaryStream($in->getString());
|
||||
|
||||
$chainData = json_decode($buffer->get($buffer->getLInt()), true);
|
||||
if(!is_array($chainData)){
|
||||
throw new BadPacketException("Failed to decode chainData JSON: " . json_last_error_msg());
|
||||
$chainDataJson = json_decode($buffer->get($buffer->getLInt()));
|
||||
$mapper = new \JsonMapper;
|
||||
$mapper->bExceptionOnMissingData = true;
|
||||
$mapper->bExceptionOnUndefinedProperty = true;
|
||||
try{
|
||||
$chainData = $mapper->map($chainDataJson, new JwtChain);
|
||||
}catch(\JsonMapper_Exception $e){
|
||||
throw BadPacketException::wrap($e);
|
||||
}
|
||||
|
||||
$vd = new Validator();
|
||||
$vd->required('chain')->isArray()->callback(function(array $data) : bool{
|
||||
return count($data) <= 3 and count(array_filter($data, '\is_string')) === count($data);
|
||||
});
|
||||
self::validate($vd, "chainData", $chainData);
|
||||
$this->chainDataJwt = $chainData;
|
||||
|
||||
$this->chainDataJwt = $chainData['chain'];
|
||||
foreach($this->chainDataJwt as $k => $chain){
|
||||
foreach($this->chainDataJwt->chain as $k => $chain){
|
||||
//validate every chain element
|
||||
try{
|
||||
$claims = Utils::getJwtClaims($chain);
|
||||
@ -164,13 +105,15 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
throw new BadPacketException("Found 'extraData' more than once in chainData");
|
||||
}
|
||||
|
||||
$extraV = new Validator();
|
||||
$extraV->required(self::I_USERNAME)->string();
|
||||
$extraV->required(self::I_UUID)->uuid();
|
||||
$extraV->required(self::I_XUID)->string()->digits()->allowEmpty(true);
|
||||
self::validate($extraV, "chain.$k.extraData", $claims['extraData']);
|
||||
|
||||
$this->extraData = $claims['extraData'];
|
||||
$mapper = new \JsonMapper;
|
||||
$mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models
|
||||
$mapper->bExceptionOnMissingData = true;
|
||||
$mapper->bExceptionOnUndefinedProperty = true;
|
||||
try{
|
||||
$this->extraData = $mapper->map($claims['extraData'], new AuthenticationData);
|
||||
}catch(\JsonMapper_Exception $e){
|
||||
throw BadPacketException::wrap($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->extraData === null){
|
||||
@ -184,40 +127,15 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
throw new BadPacketException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
$v = new Validator();
|
||||
$v->required(self::I_CLIENT_RANDOM_ID)->integer();
|
||||
$v->required(self::I_SERVER_ADDRESS)->string();
|
||||
$v->required(self::I_LANGUAGE_CODE)->string();
|
||||
|
||||
$v->required(self::I_SKIN_RESOURCE_PATCH)->string();
|
||||
|
||||
$v->required(self::I_SKIN_ID)->string();
|
||||
$v->required(self::I_SKIN_DATA)->string();
|
||||
$v->required(self::I_SKIN_HEIGHT)->integer(true);
|
||||
$v->required(self::I_SKIN_WIDTH)->integer(true);
|
||||
|
||||
$v->required(self::I_CAPE_ID, null, true)->string();
|
||||
$v->required(self::I_CAPE_DATA, null, true)->string();
|
||||
$v->required(self::I_CAPE_HEIGHT)->integer(true);
|
||||
$v->required(self::I_CAPE_WIDTH)->integer(true);
|
||||
|
||||
$v->required(self::I_GEOMETRY_DATA, null, true)->string();
|
||||
|
||||
$v->required(self::I_ANIMATION_DATA, null, true)->string();
|
||||
$v->required(self::I_ANIMATION_IMAGES, null, true)->isArray()->each(function(Validator $vSub) : void{
|
||||
$vSub->required(self::I_ANIMATION_IMAGE_HEIGHT)->integer(true);
|
||||
$vSub->required(self::I_ANIMATION_IMAGE_WIDTH)->integer(true);
|
||||
$vSub->required(self::I_ANIMATION_IMAGE_FRAMES)->numeric(); //float() doesn't accept ints ???
|
||||
$vSub->required(self::I_ANIMATION_IMAGE_TYPE)->integer(true);
|
||||
$vSub->required(self::I_ANIMATION_IMAGE_DATA)->string();
|
||||
});
|
||||
$v->required(self::I_PREMIUM_SKIN)->bool();
|
||||
$v->required(self::I_PERSONA_SKIN)->bool();
|
||||
$v->required(self::I_PERSONA_CAPE_ON_CLASSIC_SKIN)->bool();
|
||||
|
||||
self::validate($v, 'clientData', $clientData);
|
||||
|
||||
$this->clientData = $clientData;
|
||||
$mapper = new \JsonMapper;
|
||||
$mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models
|
||||
$mapper->bExceptionOnMissingData = true;
|
||||
$mapper->bExceptionOnUndefinedProperty = true;
|
||||
try{
|
||||
$this->clientData = $mapper->map($clientData, new ClientData);
|
||||
}catch(\JsonMapper_Exception $e){
|
||||
throw BadPacketException::wrap($e);
|
||||
}
|
||||
}
|
||||
|
||||
protected function encodePayload(NetworkBinaryStream $out) : void{
|
||||
|
51
src/network/mcpe/protocol/types/login/AuthenticationData.php
Normal file
51
src/network/mcpe/protocol/types/login/AuthenticationData.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||
|
||||
/**
|
||||
* Model class for LoginPacket JSON data for JsonMapper
|
||||
*/
|
||||
final class AuthenticationData{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $displayName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $identity;
|
||||
|
||||
/** @var string */
|
||||
public $titleId = ""; //TODO: find out what this is for
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $XUID;
|
||||
}
|
219
src/network/mcpe/protocol/types/login/ClientData.php
Normal file
219
src/network/mcpe/protocol/types/login/ClientData.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||
|
||||
/**
|
||||
* Model class for LoginPacket JSON data for JsonMapper
|
||||
*/
|
||||
final class ClientData{
|
||||
|
||||
/**
|
||||
* @var ClientDataAnimationFrame[]
|
||||
* @required
|
||||
*/
|
||||
public $AnimatedImageData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $CapeData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $CapeId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $CapeImageHeight;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $CapeImageWidth;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @required
|
||||
*/
|
||||
public $CapeOnClassicSkin;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $ClientRandomId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $CurrentInputMode;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $DefaultInputMode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $DeviceId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $DeviceModel;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $DeviceOS;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $GameVersion;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $GuiScale;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $LanguageCode;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @required
|
||||
*/
|
||||
public $PersonaSkin;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $PlatformOfflineId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $PlatformOnlineId;
|
||||
|
||||
/** @var string */
|
||||
public $PlatformUserId = ""; //xbox-only, apparently
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @required
|
||||
*/
|
||||
public $PremiumSkin = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SelfSignedId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $ServerAddress;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SkinAnimationData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SkinData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SkinGeometryData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SkinId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $SkinImageHeight;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $SkinImageWidth;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $SkinResourcePatch;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $ThirdPartyName;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @required
|
||||
*/
|
||||
public $ThirdPartyNameOnly;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $UIProfile;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||
|
||||
/**
|
||||
* Model class for LoginPacket JSON data for JsonMapper
|
||||
*/
|
||||
final class ClientDataAnimationFrame{
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $ImageHeight;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $ImageWidth;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
* @required
|
||||
*/
|
||||
public $Frames;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @required
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @required
|
||||
*/
|
||||
public $Image;
|
||||
}
|
36
src/network/mcpe/protocol/types/login/JwtChain.php
Normal file
36
src/network/mcpe/protocol/types/login/JwtChain.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||
|
||||
/**
|
||||
* Model class for LoginPacket JSON data for JsonMapper
|
||||
*/
|
||||
final class JwtChain{
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @required
|
||||
*/
|
||||
public $chain;
|
||||
}
|
19
tests/phpstan/stubs/JsonMapper.stub
Normal file
19
tests/phpstan/stubs/JsonMapper.stub
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
//possible bug in phpstan requires this to be defined here
|
||||
class JsonMapper_Exception extends \Exception{}
|
||||
|
||||
class JsonMapper{
|
||||
|
||||
/**
|
||||
* @template TModel of object
|
||||
*
|
||||
* @param mixed[]|object $json
|
||||
* @param TModel $object
|
||||
*
|
||||
* @return TModel
|
||||
*
|
||||
* @throws JsonMapper_Exception
|
||||
*/
|
||||
public function map($json, object $object) : object{}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user