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.
Alternative methods
Define a hacky class
I tried to make a clone of Skin class like:
use function implode;
use function in_array;
use function json_decode;
use function json_encode;
use function json_last_error_msg;
use function strlen;
/** @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...`
- 2. Modify PMMP code directly
I would simply remove the final keyword of Skin class and extend it on the plugin
Description
I would suggest one of these
Justification
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.Alternative methods
/*
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 ];
}