src/Analyzers/HeaderAnalyzer.php
protected function readChat(array $players)
    {
        $playersByNumber = [];
        foreach ($players as $player) {
            $playersByNumber[$player->number] = $player;
        }

        $messages = [];
        $messageCount = $this->readHeader('l', 4);
        for ($i = 0; $i < $messageCount; $i += 1) {
            $length = $this->readHeader('l', 4);
            if ($length <= 0) {
                continue;
            }
            $chat = $this->readHeaderRaw($length);

            // pre-game chat messages are stored as "@#%dPlayerName: Message",
            // where %d is a digit from 1 to 8 indicating player's index (or
            // colour)
            if ($chat[0] == '@' && $chat[1] == '#' && $chat[2] >= '1' && $chat[2] <= '8') {
                $chat = rtrim($chat); // throw null-termination character
                if (!empty($playersByNumber[$chat[2]])) {
                    $player = $playersByNumber[$chat[2]];
                } else {
                    // this player left before the game started
                    $player = null;
                }
                $messages[] = ChatMessage::create(null, $player, substr($chat, 3));
            }
        }
        return $messages;
    }
protected function readChat(array $players)
    {
        $playersByNumber = [];
        foreach ($players as $player) {
            $playersByNumber[$player->number] = $player;
        }

        $messages = [];
        $messageCount = $this->readHeader('l', 4);
        for ($i = 0; $i < $messageCount; $i += 1) {
            $length = $this->readHeader('l', 4);
            if ($length <= 0) {
                continue;
            }
            $chat = $this->readHeaderRaw($length);

            // pre-game chat messages are stored as "@#%dPlayerName: Message",
            // where %d is a digit from 1 to 8 indicating player's index (or
            // colour)
            if ($chat[0] == '@' && $chat[1] == '#' && $chat[2] >= '1' && $chat[2] <= '8') {
                $chat = rtrim($chat); // throw null-termination character
                if (!empty($playersByNumber[$chat[2]])) {
                    $player = $playersByNumber[$chat[2]];
                } else {
                    // this player left before the game started
                    $player = null;
                }
                $messages[] = ChatMessage::create(null, $player, substr($chat, 3));
            }
        }
        return $messages;
    }
protected function readChat ( array $ players ) { $ playersByNumber = [ ] ; foreach ( $ players as $ player ) { $ playersByNumber [ $ player -> number ] = $ player ; } $ messages = [ ] ; $ messageCount = $ this -> readHeader ( 'l' , 4 ) ; for ( $ i = 0 ; $ i < $ messageCount ; $ i += 1 ) { $ length = $ this -> readHeader ( 'l' , 4 ) ; if ( $ length <= 0 ) { continue ; } $ chat = $ this -> readHeaderRaw ( $ length ) ; // pre-game chat messages are stored as "@#%dPlayerName: Message", // where %d is a digit from 1 to 8 indicating player's index (or // colour) if ( $ chat [ 0 ] == '@' && $ chat [ 1 ] == '#' && $ chat [ 2 ] >= '1' && $ chat [ 2 ] <= '8' ) { $ chat = rtrim ( $ chat ) ; // throw null-termination character if ( ! empty ( $ playersByNumber [ $ chat [ 2 ] ] ) ) { $ player = $ playersByNumber [ $ chat [ 2 ] ] ; } else { // this player left before the game started $ player = null ; } $ messages [ ] = ChatMessage :: create ( null , $ player , substr ( $ chat , 3 ) ) ; } } return $ messages ; }
Read a block containing chat messages.

Chat block structure:
int32 count;
ChatMessage messages[count];
Chat message structure:
int32 length;
char contents[length];
Not much data is encoded in the chat message structure, so we derive
a lot of it from the `contents` string instead.

@param  array  $players  Array of `$playerId => $playerObject`, used to
associate player objects with chat messages.
@return array
Read a block containing chat messages .