From cd64346ee5e6d6788ace50173ff2bec490ce37ea Mon Sep 17 00:00:00 2001 From: Rogiel Sulzbach Date: Sun, 24 Jul 2016 19:52:14 -0300 Subject: [PATCH] Added support for replay attribute events --- src/Attribute/Attribute.php | 117 ++++++++++++++++++ src/Attribute/AttributeMap.php | 161 +++++++++++++++++++++++++ src/Attribute/GameAttributes.php | 83 +++++++++++++ src/Attribute/PlayerAttributes.php | 183 +++++++++++++++++++++++++++++ src/Replay.php | 27 ++++- 5 files changed, 570 insertions(+), 1 deletion(-) create mode 100644 src/Attribute/Attribute.php create mode 100644 src/Attribute/AttributeMap.php create mode 100644 src/Attribute/GameAttributes.php create mode 100644 src/Attribute/PlayerAttributes.php diff --git a/src/Attribute/Attribute.php b/src/Attribute/Attribute.php new file mode 100644 index 0000000..4095751 --- /dev/null +++ b/src/Attribute/Attribute.php @@ -0,0 +1,117 @@ +id = $id; + $this->namespace = $namespace; + $this->playerID = $playerID; + $this->value = $value; + } + + // ----------------------------------------------------------------------------------------------------------------- + + /** + * @return int + */ + public function getID() { + return $this->id; + } + + /** + * @return int + */ + public function getNamespace() { + return $this->namespace; + } + + /** + * @return int + */ + public function getPlayerID() { + return $this->playerID; + } + + /** + * @return string + */ + public function getValue() { + return $this->value; + } + + // ----------------------------------------------------------------------------------------------------------------- + + /** + * @return bool true if the attribute is for a player + */ + public function isPlayerAttribute() { + return $this->playerID != 16; + } + + /** + * @return bool true if the attribute is for the game + */ + public function isGameAttribute() { + return $this->playerID == 16; + } + +} \ No newline at end of file diff --git a/src/Attribute/AttributeMap.php b/src/Attribute/AttributeMap.php new file mode 100644 index 0000000..5e07c46 --- /dev/null +++ b/src/Attribute/AttributeMap.php @@ -0,0 +1,161 @@ +source = $stream->readByte(); + $this->namespace = $stream->readUInt32(); + $count = $stream->readUInt32(); + + for($i = 0; $i<$count; $i++) { + $namespace = $stream->readUInt32(); + $attrid = $stream->readUInt32(); + $scope = $stream->readByte(); + $value = trim(strrev($stream->readBytes(4))); + if(!isset($this->attributes[$scope])) { + $this->attributes[$scope] = array(); + } + $this->attributes[$scope][$attrid] = new Attribute( + $attrid, $namespace, $scope, $value + ); + } + + } + + // ----------------------------------------------------------------------------------------------------------------- + + /** + * Get the player attribute for the given player ID + * + * @param $playerID integer the player ID + * @param $attributeID integer the attribute ID + * + * @return Attribute|null + */ + public function getPlayerAttribute($playerID, $attributeID) { + if(!isset($this->attributes[$playerID])) { + return NULL; + } + $playerScope = $this->attributes[$playerID]; + if(!isset($playerScope[$attributeID])) { + return NULL; + } + return $playerScope[$attributeID]; + } + + /** + * Get a list of all player attributes for the given player ID + * + * @param $playerID integer the player ID + * + * @return Attribute[] + */ + public function getPlayerAttributes($playerID) { + if(!isset($this->attributes[$playerID])) { + return array(); + } + return $this->attributes[$playerID]; + } + + /** + * Get the game attribute given by the attribute ID + * + * @param $attributeID integer the attribute ID + * + * @return null|Attribute + */ + public function getGameAttribute($attributeID) { + return $this->getPlayerAttribute(self::GAME_ATTRIBUTES_PLAYER_ID, $attributeID); + } + + /** + * Get a list of all game attributes + * + * @return Attribute[] + */ + public function getGameAttributes() { + return $this->getPlayerAttributes(self::GAME_ATTRIBUTES_PLAYER_ID); + } + + // ----------------------------------------------------------------------------------------------------------------- + + /** + * @return int + */ + public function getSource() { + return $this->source; + } + + /** + * @return int + */ + public function getNamespace() { + return $this->namespace; + } + + /** + * @return Attribute[] + */ + public function getAttributes() { + return $this->attributes; + } + +} \ No newline at end of file diff --git a/src/Attribute/GameAttributes.php b/src/Attribute/GameAttributes.php new file mode 100644 index 0000000..d9a4920 --- /dev/null +++ b/src/Attribute/GameAttributes.php @@ -0,0 +1,83 @@ +parse($this->getVersion()->getReplayInitDataNode()); } + private function parseAttributeMap() { + $this->file->parse(); + $stream = $this->file->openStream('replay.attributes.events'); + return new AttributeMap($stream); + } + // ----------------------------------------------------------------------------------------------------------------- // EVENT PARSERS // ----------------------------------------------------------------------------------------------------------------- @@ -302,6 +314,19 @@ class Replay { return $this->initData; } + /** + * Gets the replay attribute map. If the data is not yet parsed, + * it is parsed and its values are stored in memory. + * + * @return AttributeMap + */ + public function getAttributeMap() { + if($this->attributeMap === null) { + $this->attributeMap = $this->parseAttributeMap(); + } + return $this->attributeMap; + } + // ----------------------------------------------------------------------------------------------------------------- /**