mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-19 23:44:17 +00:00
New skin API, add support for custom capes & custom geometry (#1416)
* Added support for changing skins ingame, custom capes & geometry * Use PlayerSkinPacket for setting Human skin instead of PlayerList hack
This commit is contained in:
parent
c273a46537
commit
e6cecabf3f
@ -34,6 +34,7 @@ use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Item as DroppedItem;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
@ -46,6 +47,7 @@ use pocketmine\event\player\PlayerAnimationEvent;
|
||||
use pocketmine\event\player\PlayerBedEnterEvent;
|
||||
use pocketmine\event\player\PlayerBedLeaveEvent;
|
||||
use pocketmine\event\player\PlayerBlockPickEvent;
|
||||
use pocketmine\event\player\PlayerChangeSkinEvent;
|
||||
use pocketmine\event\player\PlayerChatEvent;
|
||||
use pocketmine\event\player\PlayerCommandPreprocessEvent;
|
||||
use pocketmine\event\player\PlayerDeathEvent;
|
||||
@ -182,15 +184,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the length of a supplied skin bitmap and returns whether the length is valid.
|
||||
* @param string $skin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidSkin(string $skin) : bool{
|
||||
return strlen($skin) === 64 * 64 * 4 or strlen($skin) === 64 * 32 * 4;
|
||||
}
|
||||
|
||||
/** @var SourceInterface */
|
||||
protected $interface;
|
||||
@ -717,15 +710,36 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
public function setDisplayName(string $name){
|
||||
$this->displayName = $name;
|
||||
if($this->spawned){
|
||||
$this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getDisplayName(), $this->getSkinId(), $this->getSkinData());
|
||||
$this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getDisplayName(), $this->getSkin());
|
||||
}
|
||||
}
|
||||
|
||||
public function setSkin(string $str, string $skinId){
|
||||
parent::setSkin($str, $skinId);
|
||||
if($this->spawned){
|
||||
$this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getDisplayName(), $skinId, $str);
|
||||
/**
|
||||
* Called when a player changes their skin.
|
||||
* Plugin developers should not use this, use setSkin() and sendSkin() instead.
|
||||
*
|
||||
* @param Skin $skin
|
||||
* @param string $newSkinName
|
||||
* @param string $oldSkinName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{
|
||||
if(!$skin->isValid()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$ev = new PlayerChangeSkinEvent($this, $this->getSkin(), $skin);
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
|
||||
if($ev->isCancelled()){
|
||||
$this->sendSkin([$this]);
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->setSkin($ev->getNewSkin());
|
||||
$this->sendSkin($this->server->getOnlinePlayers());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function jump(){
|
||||
@ -2005,12 +2019,20 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!Player::isValidSkin($packet->skin)){
|
||||
$skin = new Skin(
|
||||
$packet->clientData["SkinId"],
|
||||
base64_decode($packet->clientData["SkinData"] ?? ""),
|
||||
base64_decode($packet->clientData["CapeData"] ?? ""),
|
||||
$packet->clientData["SkinGeometryName"],
|
||||
base64_decode($packet->clientData["SkinGeometry"] ?? "")
|
||||
);
|
||||
|
||||
if(!$skin->isValid()){
|
||||
$this->close("", "disconnectionScreen.invalidSkin");
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->setSkin($packet->skin, $packet->skinId);
|
||||
$this->setSkin($skin);
|
||||
|
||||
if(!$this->server->isWhitelisted($this->iusername) and $this->kick("Server is white-listed", false)){
|
||||
return true;
|
||||
|
@ -81,7 +81,7 @@ namespace pocketmine {
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const VERSION = "1.7dev";
|
||||
const API_VERSION = "3.0.0-ALPHA8";
|
||||
const API_VERSION = "3.0.0-ALPHA9";
|
||||
const CODENAME = "[REDACTED]";
|
||||
|
||||
/*
|
||||
|
@ -36,6 +36,7 @@ use pocketmine\command\SimpleCommandMap;
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\event\HandlerList;
|
||||
use pocketmine\event\level\LevelInitEvent;
|
||||
use pocketmine\event\level\LevelLoadEvent;
|
||||
@ -2283,7 +2284,7 @@ class Server{
|
||||
}
|
||||
|
||||
public function addOnlinePlayer(Player $player){
|
||||
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkinId(), $player->getSkinData());
|
||||
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin());
|
||||
|
||||
$this->playerList[$player->getRawUniqueId()] = $player;
|
||||
}
|
||||
@ -2300,15 +2301,14 @@ class Server{
|
||||
* @param UUID $uuid
|
||||
* @param int $entityId
|
||||
* @param string $name
|
||||
* @param string $skinId
|
||||
* @param string $skinData
|
||||
* @param Skin $skin
|
||||
* @param Player[]|null $players
|
||||
*/
|
||||
public function updatePlayerListData(UUID $uuid, int $entityId, string $name, string $skinId, string $skinData, array $players = null){
|
||||
public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, array $players = null){
|
||||
$pk = new PlayerListPacket();
|
||||
$pk->type = PlayerListPacket::TYPE_ADD;
|
||||
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, $skinId, $skinData);
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, $skin);
|
||||
$this->broadcastPacket($players ?? $this->playerList, $pk);
|
||||
}
|
||||
|
||||
@ -2330,7 +2330,7 @@ class Server{
|
||||
$pk = new PlayerListPacket();
|
||||
$pk->type = PlayerListPacket::TYPE_ADD;
|
||||
foreach($this->playerList as $player){
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkinId(), $player->getSkinData());
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin());
|
||||
}
|
||||
|
||||
$p->dataPacket($pk);
|
||||
|
@ -37,6 +37,7 @@ use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
@ -60,8 +61,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
public $height = 1.8;
|
||||
public $eyeHeight = 1.62;
|
||||
|
||||
protected $skinId;
|
||||
protected $skin = "";
|
||||
/** @var Skin */
|
||||
protected $skin;
|
||||
|
||||
protected $foodTickTimer = 0;
|
||||
|
||||
@ -71,19 +72,22 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
protected $baseOffset = 1.62;
|
||||
|
||||
public function __construct(Level $level, CompoundTag $nbt){
|
||||
if($this->skin === "" and (!isset($nbt->Skin) or !isset($nbt->Skin->Data) or !Player::isValidSkin($nbt->Skin->Data->getValue()))){
|
||||
if($this->skin === null and (!isset($nbt->Skin) or !isset($nbt->Skin->Data) or !Player::isValidSkin($nbt->Skin->Data->getValue()))){
|
||||
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
|
||||
}
|
||||
|
||||
parent::__construct($level, $nbt);
|
||||
}
|
||||
|
||||
public function getSkinData(){
|
||||
return $this->skin;
|
||||
}
|
||||
|
||||
public function getSkinId(){
|
||||
return $this->skinId;
|
||||
/**
|
||||
* Checks the length of a supplied skin bitmap and returns whether the length is valid.
|
||||
*
|
||||
* @param string $skin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidSkin(string $skin) : bool{
|
||||
return strlen($skin) === 64 * 64 * 4 or strlen($skin) === 64 * 32 * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,16 +105,35 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @param string $skinId
|
||||
* Returns a Skin object containing information about this human's skin.
|
||||
* @return Skin
|
||||
*/
|
||||
public function setSkin(string $str, string $skinId){
|
||||
if(!Player::isValidSkin($str)){
|
||||
public function getSkin() : Skin{
|
||||
return $this->skin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the human's skin. This will not send any update to viewers, you need to do that manually using
|
||||
* {@link sendSkin}.
|
||||
*
|
||||
* @param Skin $skin
|
||||
*/
|
||||
public function setSkin(Skin $skin) : void{
|
||||
if(!$skin->isValid()){
|
||||
throw new \InvalidStateException("Specified skin is not valid, must be 8KiB or 16KiB");
|
||||
}
|
||||
|
||||
$this->skin = $str;
|
||||
$this->skinId = $skinId;
|
||||
$this->skin = $skin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player[] $targets
|
||||
*/
|
||||
public function sendSkin(array $targets) : void{
|
||||
$pk = new PlayerSkinPacket();
|
||||
$pk->uuid = $this->getUniqueId();
|
||||
$pk->skin = $this->skin;
|
||||
$this->server->broadcastPacket($targets, $pk);
|
||||
}
|
||||
|
||||
public function jump(){
|
||||
@ -287,10 +310,13 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
if(isset($this->namedtag->Skin) and $this->namedtag->Skin instanceof CompoundTag){
|
||||
$this->setSkin($this->namedtag->Skin["Data"], $this->namedtag->Skin["Name"]);
|
||||
$this->setSkin(new Skin(
|
||||
$this->namedtag->Skin["Name"],
|
||||
$this->namedtag->Skin["Data"]
|
||||
));
|
||||
}
|
||||
|
||||
$this->uuid = UUID::fromData((string) $this->getId(), $this->getSkinData(), $this->getNameTag());
|
||||
$this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag());
|
||||
}
|
||||
|
||||
protected function initEntity(){
|
||||
@ -467,10 +493,11 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
$this->namedtag->SelectedInventorySlot = new IntTag("SelectedInventorySlot", $this->inventory->getHeldItemIndex());
|
||||
}
|
||||
|
||||
if(strlen($this->getSkinData()) > 0){
|
||||
if($this->skin !== null){
|
||||
$this->namedtag->Skin = new CompoundTag("Skin", [
|
||||
new StringTag("Data", $this->getSkinData()),
|
||||
new StringTag("Name", $this->getSkinId())
|
||||
//TODO: save cape & geometry
|
||||
new StringTag("Data", $this->skin->getSkinData()),
|
||||
new StringTag("Name", $this->skin->getSkinId())
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -479,14 +506,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
if($player !== $this and !isset($this->hasSpawned[$player->getLoaderId()])){
|
||||
$this->hasSpawned[$player->getLoaderId()] = $player;
|
||||
|
||||
if(!Player::isValidSkin($this->skin)){
|
||||
if(!$this->skin->isValid()){
|
||||
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
|
||||
}
|
||||
|
||||
if(!($this instanceof Player)){
|
||||
$this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getName(), $this->skinId, $this->skin, [$player]);
|
||||
}
|
||||
|
||||
$pk = new AddPlayerPacket();
|
||||
$pk->uuid = $this->getUniqueId();
|
||||
$pk->username = $this->getName();
|
||||
@ -502,7 +525,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
$this->inventory->sendArmorContents($player);
|
||||
|
||||
if(!($this instanceof Player)){
|
||||
$this->server->removePlayerListData($this->getUniqueId(), [$player]);
|
||||
$this->sendSkin([$player]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
src/pocketmine/entity/Skin.php
Normal file
90
src/pocketmine/entity/Skin.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?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\entity;
|
||||
|
||||
class Skin{
|
||||
|
||||
/** @var string */
|
||||
private $skinId;
|
||||
/** @var string */
|
||||
private $skinData;
|
||||
/** @var string */
|
||||
private $capeData;
|
||||
/** @var string */
|
||||
private $geometryName;
|
||||
/** @var string */
|
||||
private $geometryData;
|
||||
|
||||
public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){
|
||||
$this->skinId = $skinId;
|
||||
$this->skinData = $skinData;
|
||||
$this->capeData = $capeData;
|
||||
$this->geometryName = $geometryName;
|
||||
$this->geometryData = $geometryData;
|
||||
}
|
||||
|
||||
public function isValid() : bool{
|
||||
return (
|
||||
$this->skinId !== "" and
|
||||
(($s = strlen($this->skinData)) === 16384 or $s === 8192) and
|
||||
($this->capeData === "" or strlen($this->capeData) === 8192)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSkinId() : string{
|
||||
return $this->skinId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSkinData() : string{
|
||||
return $this->skinData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCapeData() : string{
|
||||
return $this->capeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGeometryName() : string{
|
||||
return $this->geometryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGeometryData() : string{
|
||||
return $this->geometryData;
|
||||
}
|
||||
|
||||
}
|
78
src/pocketmine/event/player/PlayerChangeSkinEvent.php
Normal file
78
src/pocketmine/event/player/PlayerChangeSkinEvent.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?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\event\player;
|
||||
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\Player;
|
||||
|
||||
/**
|
||||
* Called when a player changes their skin in-game.
|
||||
*/
|
||||
class PlayerChangeSkinEvent extends PlayerEvent implements Cancellable{
|
||||
public static $handlerList = null;
|
||||
|
||||
/** @var Skin */
|
||||
private $oldSkin;
|
||||
/** @var Skin */
|
||||
private $newSkin;
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
* @param Skin $oldSkin
|
||||
* @param Skin $newSkin
|
||||
*/
|
||||
public function __construct(Player $player, Skin $oldSkin, Skin $newSkin){
|
||||
$this->player = $player;
|
||||
$this->oldSkin = $oldSkin;
|
||||
$this->newSkin = $newSkin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Skin
|
||||
*/
|
||||
public function getOldSkin() : Skin{
|
||||
return $this->oldSkin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Skin
|
||||
*/
|
||||
public function getNewSkin() : Skin{
|
||||
return $this->newSkin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Skin $skin
|
||||
* @throws \InvalidArgumentException if the specified skin is not valid
|
||||
*/
|
||||
public function setNewSkin(Skin $skin) : void{
|
||||
if(!$skin->isValid()){
|
||||
throw new \InvalidArgumentException("Skin format is invalid");
|
||||
}
|
||||
|
||||
$this->newSkin = $skin;
|
||||
}
|
||||
|
||||
}
|
@ -228,7 +228,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
|
||||
}
|
||||
|
||||
public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{
|
||||
return false; //TODO
|
||||
return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName);
|
||||
}
|
||||
|
||||
public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{
|
||||
|
@ -48,11 +48,6 @@ class LoginPacket extends DataPacket{
|
||||
/** @var string */
|
||||
public $serverAddress;
|
||||
|
||||
/** @var string */
|
||||
public $skinId;
|
||||
/** @var string */
|
||||
public $skin = "";
|
||||
|
||||
/** @var array (the "chain" index contains one or more JWTs) */
|
||||
public $chainData = [];
|
||||
/** @var string */
|
||||
@ -102,11 +97,6 @@ class LoginPacket extends DataPacket{
|
||||
|
||||
$this->clientId = $this->clientData["ClientRandomId"] ?? null;
|
||||
$this->serverAddress = $this->clientData["ServerAddress"] ?? null;
|
||||
$this->skinId = $this->clientData["SkinId"] ?? null;
|
||||
|
||||
if(isset($this->clientData["SkinData"])){
|
||||
$this->skin = base64_decode($this->clientData["SkinData"]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function encodePayload(){
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol;
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
|
||||
@ -55,11 +56,13 @@ class PlayerListPacket extends DataPacket{
|
||||
$entry->uuid = $this->getUUID();
|
||||
$entry->entityUniqueId = $this->getEntityUniqueId();
|
||||
$entry->username = $this->getString();
|
||||
$entry->skinId = $this->getString();
|
||||
$entry->skinData = $this->getString();
|
||||
$entry->capeData = $this->getString();
|
||||
$entry->geometryModel = $this->getString();
|
||||
$entry->geometryData = $this->getString();
|
||||
$entry->skin = new Skin(
|
||||
$this->getString(), //id
|
||||
$this->getString(), //data
|
||||
$this->getString(), //cape
|
||||
$this->getString(), //geometry name
|
||||
$this->getString() //geometry data
|
||||
);
|
||||
$entry->xboxUserId = $this->getString();
|
||||
}else{
|
||||
$entry->uuid = $this->getUUID();
|
||||
@ -77,11 +80,11 @@ class PlayerListPacket extends DataPacket{
|
||||
$this->putUUID($entry->uuid);
|
||||
$this->putEntityUniqueId($entry->entityUniqueId);
|
||||
$this->putString($entry->username);
|
||||
$this->putString($entry->skinId);
|
||||
$this->putString($entry->skinData);
|
||||
$this->putString($entry->capeData);
|
||||
$this->putString($entry->geometryModel);
|
||||
$this->putString($entry->geometryData);
|
||||
$this->putString($entry->skin->getSkinId());
|
||||
$this->putString($entry->skin->getSkinData());
|
||||
$this->putString($entry->skin->getCapeData());
|
||||
$this->putString($entry->skin->getGeometryName());
|
||||
$this->putString($entry->skin->getGeometryData());
|
||||
$this->putString($entry->xboxUserId);
|
||||
}else{
|
||||
$this->putUUID($entry->uuid);
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
@ -34,41 +35,37 @@ class PlayerSkinPacket extends DataPacket{
|
||||
/** @var UUID */
|
||||
public $uuid;
|
||||
/** @var string */
|
||||
public $skinId;
|
||||
public $oldSkinName = "";
|
||||
/** @var string */
|
||||
public $newSkinName;
|
||||
/** @var string */
|
||||
public $oldSkinName;
|
||||
/** @var string */
|
||||
public $skinData;
|
||||
/** @var string */
|
||||
public $capeData;
|
||||
/** @var string */
|
||||
public $geometryModel;
|
||||
/** @var string */
|
||||
public $geometryData;
|
||||
public $newSkinName = "";
|
||||
/** @var Skin */
|
||||
public $skin;
|
||||
|
||||
|
||||
protected function decodePayload(){
|
||||
$this->uuid = $this->getUUID();
|
||||
$this->skinId = $this->getString();
|
||||
|
||||
$skinId = $this->getString();
|
||||
$this->newSkinName = $this->getString();
|
||||
$this->oldSkinName = $this->getString();
|
||||
$this->skinData = $this->getString();
|
||||
$this->capeData = $this->getString();
|
||||
$this->geometryModel = $this->getString();
|
||||
$this->geometryData = $this->getString();
|
||||
$skinData = $this->getString();
|
||||
$capeData = $this->getString();
|
||||
$geometryModel = $this->getString();
|
||||
$geometryData = $this->getString();
|
||||
|
||||
$this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData);
|
||||
}
|
||||
|
||||
protected function encodePayload(){
|
||||
$this->putUUID($this->uuid);
|
||||
$this->putString($this->skinId);
|
||||
|
||||
$this->putString($this->skin->getSkinId());
|
||||
$this->putString($this->newSkinName);
|
||||
$this->putString($this->oldSkinName);
|
||||
$this->putString($this->skinData);
|
||||
$this->putString($this->capeData);
|
||||
$this->putString($this->geometryModel);
|
||||
$this->putString($this->geometryData);
|
||||
$this->putString($this->skin->getSkinData());
|
||||
$this->putString($this->skin->getCapeData());
|
||||
$this->putString($this->skin->getGeometryName());
|
||||
$this->putString($this->skin->getGeometryData());
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
class PlayerListEntry{
|
||||
@ -33,16 +34,8 @@ class PlayerListEntry{
|
||||
public $entityUniqueId;
|
||||
/** @var string */
|
||||
public $username;
|
||||
/** @var string */
|
||||
public $skinId;
|
||||
/** @var string */
|
||||
public $skinData;
|
||||
/** @var string */
|
||||
public $capeData; //TODO
|
||||
/** @var string */
|
||||
public $geometryModel; //TODO
|
||||
/** @var string */
|
||||
public $geometryData; //TODO
|
||||
/** @var Skin */
|
||||
public $skin;
|
||||
/** @var string */
|
||||
public $xboxUserId; //TODO
|
||||
|
||||
@ -53,26 +46,12 @@ class PlayerListEntry{
|
||||
return $entry;
|
||||
}
|
||||
|
||||
public static function createAdditionEntry(
|
||||
UUID $uuid,
|
||||
int $entityUniqueId,
|
||||
string $username,
|
||||
string $skinId,
|
||||
string $skinData,
|
||||
string $capeData = "",
|
||||
string $geometryModel = "",
|
||||
string $geometryData = "",
|
||||
string $xboxUserId = ""
|
||||
) : PlayerListEntry{
|
||||
public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, Skin $skin, string $xboxUserId = "") : PlayerListEntry{
|
||||
$entry = new PlayerListEntry();
|
||||
$entry->uuid = $uuid;
|
||||
$entry->entityUniqueId = $entityUniqueId;
|
||||
$entry->username = $username;
|
||||
$entry->skinId = $skinId;
|
||||
$entry->skinData = $skinData;
|
||||
$entry->capeData = $capeData;
|
||||
$entry->geometryModel = $geometryModel;
|
||||
$entry->geometryData = $geometryData;
|
||||
$entry->skin = $skin;
|
||||
$entry->xboxUserId = $xboxUserId;
|
||||
|
||||
return $entry;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit eec5da2443b84821bd7e7224adea4921c81dc674
|
||||
Subproject commit 857e8afab4a7a34c7235ce06e43796bf64581e3d
|
@ -1 +1 @@
|
||||
Subproject commit 9249723281f7ee63e51cd51862682187bbe70ad2
|
||||
Subproject commit 7e084a9eea099fadf0eb52c683b367b340a2b570
|
Loading…
x
Reference in New Issue
Block a user