$maxLength){ throw new InvalidSkinException("$name must be at most $maxLength bytes, but have " . strlen($string) . " bytes"); } } public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){ self::checkLength($skinId, "Skin ID", Limits::INT16_MAX); self::checkLength($geometryName, "Geometry name", Limits::INT16_MAX); self::checkLength($geometryData, "Geometry data", Limits::INT32_MAX); if($skinId === ""){ throw new InvalidSkinException("Skin ID must not be empty"); } $len = strlen($skinData); if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){ throw new InvalidSkinException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")"); } if($capeData !== "" && strlen($capeData) !== 8192){ throw new InvalidSkinException("Invalid cape data size " . strlen($capeData) . " bytes (must be exactly 8192 bytes)"); } if($geometryData !== ""){ try{ $decodedGeometry = (new CommentedJsonDecoder())->decode($geometryData); }catch(\RuntimeException $e){ throw new InvalidSkinException("Invalid geometry data: " . $e->getMessage(), 0, $e); } /* * 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, JSON_THROW_ON_ERROR); } $this->skinId = $skinId; $this->skinData = $skinData; $this->capeData = $capeData; $this->geometryName = $geometryName; $this->geometryData = $geometryData; } public function getSkinId() : string{ return $this->skinId; } public function getSkinData() : string{ return $this->skinData; } public function getCapeData() : string{ return $this->capeData; } public function getGeometryName() : string{ return $this->geometryName; } public function getGeometryData() : string{ return $this->geometryData; } }