public function decode()
{
$this->protocol = $this->getInt();
if (!in_array($this->protocol, Info::ACCEPTED_PROTOCOLS)) {
return;
//Do not attempt to decode for non-accepted protocols
}
$str = zlib_decode($this->get($this->getInt()), 1024 * 1024 * 64);
$this->setBuffer($str, 0);
$time = time();
$chainData = json_decode($this->get($this->getLInt()))->{"chain"};
// Start with the trusted one
$chainKey = self::MOJANG_PUBKEY;
while (!empty($chainData)) {
foreach ($chainData as $index => $chain) {
list($verified, $webtoken) = $this->decodeToken($chain, $chainKey);
if (isset($webtoken["extraData"])) {
if (isset($webtoken["extraData"]["displayName"])) {
$this->username = $webtoken["extraData"]["displayName"];
}
if (isset($webtoken["extraData"]["identity"])) {
$this->clientUUID = $webtoken["extraData"]["identity"];
}
}
if ($verified) {
$verified = isset($webtoken["nbf"]) && $webtoken["nbf"] <= $time && isset($webtoken["exp"]) && $webtoken["exp"] > $time;
}
if ($verified and isset($webtoken["identityPublicKey"])) {
// Looped key chain. #blamemojang
if ($webtoken["identityPublicKey"] != self::MOJANG_PUBKEY) {
$chainKey = $webtoken["identityPublicKey"];
}
break;
} elseif ($chainKey === null) {
// We have already gave up
break;
}
}
if (!$verified && $chainKey !== null) {
$chainKey = null;
} else {
unset($chainData[$index]);
}
}
list($verified, $skinToken) = $this->decodeToken($this->get($this->getLInt()), $chainKey);
if (isset($skinToken["ClientRandomId"])) {
$this->clientId = $skinToken["ClientRandomId"];
}
if (isset($skinToken["ServerAddress"])) {
$this->serverAddress = $skinToken["ServerAddress"];
}
if (isset($skinToken["SkinData"])) {
$this->skin = base64_decode($skinToken["SkinData"]);
}
if (isset($skinToken["SkinId"])) {
$this->skinId = $skinToken["SkinId"];
}
if ($verified) {
$this->identityPublicKey = $chainKey;
}
}