/** * @param Replay $replay * @param BinaryReader $br * @param int $frameNumber * @return Replication */ public static function deserialize($replay, $br, $frameNumber) { $r = new self(); $r->actorId = bindec(strrev($br->readBits(10))); $r->channelState = $br->readBit(); if (!$r->channelState) { $replay->closeActor($r->actorId, $frameNumber); return $r; } $r->actorState = $br->readBit(); if ($r->actorState) { // New actor $r->propertyFlag = $br->readBit(); // seems to always be 0 since we are creating a new actor $r->actorObjectId = bindec(strrev($br->readBits(8))); $actor = $replay->createActor($r->actorId, $r->actorObjectId, $frameNumber); $actor->deserializeInit($br); print "Actor #{$actor->id} {$actor->class} R:{$actor->rotator} P:{$actor->position} O:{$actor->orientation}\n"; } else { // Existing actor print "existing actor\n"; $actor = $replay->getActor($r->actorId); while ($br->readBit()) { $actor->updateProperty(ActorProperty::deserialize($replay, $br, $actor)); } } return $r; }
/** * Parses the given file path as a replay and returns a Replay. * * @param string $path * @return Replay */ public static function parse($path) { $replay = new Replay(); if (!is_readable($path)) { throw new \Exception('Cannot read replay file.'); } if (!filesize($path)) { throw new \Exception('No data in replay file.'); } $handle = fopen($path, 'rb'); // Size of properties section self::readInt($handle); // CRC self::readInt($handle); $replay->version = self::readInt($handle) . '.' . self::readInt($handle); $replay->type = self::readString($handle); $replay->properties = self::readProperties($handle); // Size of remaining data self::readInt($handle); // Unknown 4 byte separator self::readInt($handle); $replay->levels = self::readStrings($handle); $replay->keyFrames = self::readKeyFrames($handle); $frameData = self::readFrameData($handle); $replay->log = self::readLog($handle); $replay->ticks = self::readTicks($handle); $replay->packages = self::readStrings($handle); $replay->objects = self::readStrings($handle); $replay->names = self::readStrings($handle); $replay->classes = self::readClasses($handle); $replay->propertyTree = self::readPropertyTree($handle); fclose($handle); $replay->buildCache(); $replay->frames = self::deserializeFrames($replay, $frameData); return $replay; }