I would suggest one of these
When I tried to set the skin of an entity, an exception [Server thread/CRITICAL]: InvalidArgumentException: "Invalid skin data size 32769 bytes (allowed sizes: 8192, 16384, 65536)" (EXCEPTION) occurred because the skin size changed due to the rotation of the geometry. I needed a way to pass the skin size limitation.
<?php
/*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*/
declare(strict_types=1);
namespace your\plugin;
use function implode;
use function in_array;
use function json_decode;
use function json_encode;
use function json_last_error_msg;
use function strlen;
class DynamicSkin {
protected static $acceptedSkinSizes = [
64 * 32 * 4,
64 * 64 * 4,
128 * 128 * 4
];
/** @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 = ""){
if($skinId === ""){
throw new \InvalidArgumentException("Skin ID must not be empty");
}
$len = strlen($skinData);
if(!in_array($len, self::$acceptedSkinSizes, true)){
throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::$acceptedSkinSizes) . ")");
}
if($capeData !== "" and strlen($capeData) !== 8192){
throw new \InvalidArgumentException("Invalid cape data size " . strlen($capeData) . " bytes (must be exactly 8192 bytes)");
}
if($geometryData !== ""){
$decodedGeometry = json_decode($geometryData);
if($decodedGeometry === false){
throw new \InvalidArgumentException("Invalid geometry data (" . json_last_error_msg() . ")");
}
/*
* Hack to cut down on network overhead due to skins, by un-pretty-printing geometry JSON.
*
* Mojang, some stupid reason, send every single model for every single skin in the selected skin-pack.
* Not only that, they are pretty-printed.
* TODO: find out what model crap can be safely dropped from the packet (unless it gets fixed first)
*/
$geometryData = json_encode($decodedGeometry);
}
$this->skinId = $skinId;
$this->skinData = $skinData;
$this->capeData = $capeData;
$this->geometryName = $geometryName;
$this->geometryData = $geometryData;
}
public static function addAcceptedSkinSize(int $byte) : bool {
if (in_array($byte, self::$acceptedSkinSizes)) {
return false;
}
self::$acceptedSkinSizes[] = $byte;
return true;
}
/**
* @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;
}
}
And a problem happens when a player joins after the skin has changed
[Server thread/CRITICAL]: TypeError: "Argument 4 passed to pocketmine\network\mcpe\protocol\types\PlayerListEntry::createAdditionEntry() must be an instance of pocketmine\entity\Skin, instance of your\plugin\DynamicSkin given...
These sizes are the only sizes accepted by the game, regardless of geometry.
Most helpful comment
These sizes are the only sizes accepted by the game, regardless of geometry.