mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-12 00:39:45 +00:00
Friendly BC skins (persona not supported)
This commit is contained in:
parent
635bb08fb9
commit
e2fc7cdf88
@ -1917,22 +1917,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->uuid = UUID::fromString($packet->clientUUID);
|
||||
$this->rawUUID = $this->uuid->toBinary();
|
||||
|
||||
$animations = [];
|
||||
foreach($packet->clientData["AnimatedImageData"] as $animatedData){
|
||||
$animations[] = new SkinAnimation(new SerializedImage($animatedData["ImageHeight"], $animatedData["ImageWidth"], base64_decode($animatedData["Image"])), $animatedData["Type"], $animatedData["Frames"]);
|
||||
}
|
||||
$skin = new Skin(
|
||||
$packet->clientData["SkinId"],
|
||||
base64_decode($packet->clientData["SkinData"] ?? ""),
|
||||
base64_decode($packet->clientData["CapeData"] ?? ""),
|
||||
base64_decode($packet->clientData["SkinResourcePatch"] ?? ""),
|
||||
new SerializedImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData"] ?? "")),
|
||||
$animations,
|
||||
new SerializedImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "")),
|
||||
base64_decode($packet->clientData["SkinGeometryData"] ?? ""),
|
||||
base64_decode($packet->clientData["AnimationData"] ?? ""),
|
||||
$packet->clientData["PremiumSkin"] ?? false,
|
||||
$packet->clientData["PersonaSkin"] ?? false,
|
||||
$packet->clientData["CapeOnClassicSkin"] ?? false,
|
||||
$packet->clientData["CapeId"] ?? ""
|
||||
base64_decode($packet->clientData["SkinGeometryData"] ?? "")
|
||||
);
|
||||
|
||||
if(!$skin->isValid()){
|
||||
|
@ -120,16 +120,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
protected static function deserializeSkinNBT(CompoundTag $skinTag) : Skin{
|
||||
$skin = new Skin(
|
||||
$skinTag->getString("Name"),
|
||||
$skinTag->getString("SkinResourcePatch", ""),
|
||||
new SerializedImage($skinTag->getInt("SkinImageHeight"), $skinTag->getInt("SkinImageWidth"), $skinTag->getByteArray("Data")),
|
||||
"", //TODO: animations
|
||||
new SerializedImage($skinTag->getInt("CapeImageHeight"), $skinTag->getInt("CapeImageWidth"), $skinTag->getByteArray("CapeData")),
|
||||
$skinTag->getByteArray("GeometryData", ""),
|
||||
$skinTag->getByteArray("AnimationData", ""),
|
||||
$skinTag->getByte("PremiumSkin") === 1,
|
||||
$skinTag->getByte("PersonaSkin") === 1,
|
||||
$skinTag->getByte("CapeOnClassic") === 1,
|
||||
$skinTag->getString("CapeId", "")
|
||||
$skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM)
|
||||
$skinTag->getByteArray("CapeData", ""),
|
||||
$skinTag->getString("GeometryName", ""),
|
||||
$skinTag->getByteArray("GeometryData", "")
|
||||
);
|
||||
$skin->validate();
|
||||
return $skin;
|
||||
@ -839,19 +833,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
if($this->skin !== null){
|
||||
$this->namedtag->setTag(new CompoundTag("Skin", [
|
||||
new StringTag("Name", $this->skin->getSkinId()),
|
||||
new StringTag("SkinResourcePatch", $this->skin->getSkinResourcePatch()),
|
||||
new ByteArrayTag("Data", $this->skin->getSkinData()->getData()),
|
||||
new IntTag("SkinImageHeight", $this->skin->getSkinData()->getHeight()),
|
||||
new IntTag("SkinImageWidth", $this->skin->getSkinData()->getWidth()),
|
||||
new ByteArrayTag("CapeData", $this->skin->getCapeData()->getData()),
|
||||
new IntTag("CapeImageHeight", $this->skin->getCapeData()->getHeight()),
|
||||
new IntTag("CapeImageWidth", $this->skin->getCapeData()->getWidth()),
|
||||
new ByteArrayTag("GeometryData", $this->skin->getGeometryData()),
|
||||
new ByteArrayTag("AnimationData", $this->skin->getAnimationData()),
|
||||
new ByteTag("PremiumSkin", $this->skin->getPremium() ? 1 : 0),
|
||||
new ByteTag("PersonaSkin", $this->skin->getPersona() ? 1 : 0),
|
||||
new ByteTag("CapeOnClassic", $this->skin->getCapeOnClassic() ? 1 : 0),
|
||||
new StringTag("CapeId", $this->skin->getCapeId())
|
||||
new ByteArrayTag("Data", $this->skin->getSkinData()),
|
||||
new ByteArrayTag("CapeData", $this->skin->getCapeData()),
|
||||
new StringTag("GeometryName", $this->skin->getGeometryName()),
|
||||
new ByteArrayTag("GeometryData", $this->skin->getGeometryData())
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
@ -41,38 +41,20 @@ class Skin{
|
||||
/** @var string */
|
||||
private $skinId;
|
||||
/** @var string */
|
||||
private $skinResourcePatch;
|
||||
/** @var SerializedImage */
|
||||
private $skinData;
|
||||
/** @var SkinAnimation[] */
|
||||
private $animations = [];
|
||||
/** @var SerializedImage */
|
||||
/** @var string */
|
||||
private $capeData;
|
||||
/** @var string */
|
||||
private $geometryName;
|
||||
/** @var string */
|
||||
private $geometryData;
|
||||
/** @var string */
|
||||
private $animationData;
|
||||
/** @var bool */
|
||||
private $premium;
|
||||
/** @var bool */
|
||||
private $persona;
|
||||
/** @var bool */
|
||||
private $capeOnClassic;
|
||||
/** @var string */
|
||||
private $capeId;
|
||||
|
||||
public function __construct(string $skinId, string $skinResourcePatch, SerializedImage $skinData, array $animations = [], SerializedImage $capeData = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $capeOnClassic = false, string $capeId = ""){
|
||||
public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){
|
||||
$this->skinId = $skinId;
|
||||
$this->skinResourcePatch = $skinResourcePatch;
|
||||
$this->skinData = $skinData;
|
||||
$this->animations = $animations;
|
||||
$this->capeData = $capeData;
|
||||
$this->geometryName = $geometryName;
|
||||
$this->geometryData = $geometryData;
|
||||
$this->animationData = $animationData;
|
||||
$this->premium = $premium;
|
||||
$this->persona = $persona;
|
||||
$this->capeOnClassic = $capeOnClassic;
|
||||
$this->capeId = $capeId;
|
||||
}
|
||||
|
||||
public static function convertToLegacyName(string $name) : string{
|
||||
@ -99,14 +81,13 @@ class Skin{
|
||||
if($this->skinId === ""){
|
||||
throw new \InvalidArgumentException("Skin ID must not be empty");
|
||||
}
|
||||
//Broken with Persona skins
|
||||
/*$len = strlen($this->skinData->getData());
|
||||
$len = strlen($this->skinData);
|
||||
if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){
|
||||
throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")");
|
||||
}
|
||||
if($this->capeData->getData() !== "" and strlen($this->capeData->getData()) !== 8192){
|
||||
throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData->getData()) . " bytes (must be exactly 8192 bytes)");
|
||||
}*/
|
||||
if($this->capeData !== "" and strlen($this->capeData) !== 8192){
|
||||
throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)");
|
||||
}
|
||||
//TODO: validate geometry
|
||||
}
|
||||
|
||||
@ -120,29 +101,22 @@ class Skin{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSkinResourcePatch() : string{
|
||||
return $this->skinResourcePatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SerializedImage
|
||||
*/
|
||||
public function getSkinData() : SerializedImage{
|
||||
public function getSkinData() : string{
|
||||
return $this->skinData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SkinAnimation[]
|
||||
* @return string
|
||||
*/
|
||||
public function getAnimations() : array{
|
||||
return $this->animations;
|
||||
public function getCapeData() : string{
|
||||
return $this->capeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SerializedImage
|
||||
* @return string
|
||||
*/
|
||||
public function getCapeData() : SerializedImage{
|
||||
return $this->capeData ?? new SerializedImage(0, 0, "");
|
||||
public function getGeometryName() : string{
|
||||
return $this->geometryName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,48 +126,6 @@ class Skin{
|
||||
return $this->geometryData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAnimationData() : string{
|
||||
return $this->animationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getPremium() : bool{
|
||||
return $this->premium;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getPersona() : bool{
|
||||
return $this->persona;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getCapeOnClassic() : bool{
|
||||
return $this->capeOnClassic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCapeId() : string{
|
||||
return $this->capeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFullSkinId() : string{
|
||||
return $this->skinId . "_" . $this->capeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack to cut down on network overhead due to skins, by un-pretty-printing geometry JSON.
|
||||
*
|
||||
|
@ -97,7 +97,7 @@ class FloatingTextParticle extends Particle{
|
||||
|
||||
$add = new PlayerListPacket();
|
||||
$add->type = PlayerListPacket::TYPE_ADD;
|
||||
$add->entries = [PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", Skin::convertToLegacyName("geometry.humanoid.custom"), SerializedImage::fromLegacy(str_repeat("\x00", 8192))))];
|
||||
$add->entries = [PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", str_repeat("\x00", 8192), "", Skin::convertToLegacyName("geometry.humanoid.custom"), ""))];
|
||||
$p[] = $add;
|
||||
|
||||
$pk = new AddPlayerPacket();
|
||||
|
@ -95,29 +95,29 @@ class NetworkBinaryStream extends BinaryStream{
|
||||
$capeId = $this->getString();
|
||||
$fullSkinId = $this->getString();
|
||||
|
||||
return new Skin(
|
||||
$skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId
|
||||
);
|
||||
return new Skin($skinId, $skinData->getData(), $capeData->getData(), $skinResourcePatch, $geometryData);
|
||||
}
|
||||
|
||||
public function putSkin(Skin $skin){
|
||||
$this->putString($skin->getSkinId());
|
||||
$this->putString($skin->getSkinResourcePatch());
|
||||
$this->putImage($skin->getSkinData());
|
||||
$this->putLInt(count($skin->getAnimations()));
|
||||
foreach($skin->getAnimations() as $animation){
|
||||
$this->putString($skin->getGeometryName()); //resource patch
|
||||
$this->putImage(SerializedImage::fromLegacy($skin->getSkinData()));
|
||||
/** @var SkinAnimation[] $animations */
|
||||
$animations = [];
|
||||
$this->putLInt(count($animations));
|
||||
foreach($animations as $animation){
|
||||
$this->putImage($animation->getImage());
|
||||
$this->putLInt($animation->getType());
|
||||
$this->putLFloat($animation->getFrames());
|
||||
}
|
||||
$this->putImage($skin->getCapeData());
|
||||
$this->putImage(new SerializedImage(0, 0, $skin->getCapeData()));
|
||||
$this->putString($skin->getGeometryData());
|
||||
$this->putString($skin->getAnimationData());
|
||||
$this->putBool($skin->getPremium());
|
||||
$this->putBool($skin->getPersona());
|
||||
$this->putBool($skin->getCapeOnClassic());
|
||||
$this->putString($skin->getCapeId());
|
||||
$this->putString($skin->getFullSkinId());
|
||||
$this->putString(""); //animation data
|
||||
$this->putBool(false); //isPremium
|
||||
$this->putBool(false); //isPersona
|
||||
$this->putBool(false); //isCapeOnClassic
|
||||
$this->putString(""); //capeId
|
||||
$this->putString(""); //fullskinId
|
||||
}
|
||||
|
||||
public function getImage() : SerializedImage{
|
||||
|
Loading…
x
Reference in New Issue
Block a user