Completed
Pull Request — v3 (#471)
by
unknown
04:53
created

Gamespy   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 59.46%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 0
loc 153
ccs 22
cts 37
cp 0.5946
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A processResponse() 0 27 4
B processStatus() 0 66 8
1
<?php
2
/**
3
 * This file is part of GameQ.
4
 *
5
 * GameQ is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * GameQ is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace GameQ\Protocols;
20
21
use GameQ\Protocol;
22
use GameQ\Buffer;
23
use GameQ\Result;
24
use \GameQ\Exception\Protocol as Exception;
25
26
/**
27
 * GameSpy Protocol class
28
 *
29
 * @author Austin Bischoff <[email protected]>
30
 */
31
class Gamespy extends Protocol
32
{
33
34
    /**
35
     * Array of packets we want to look up.
36
     * Each key should correspond to a defined method in this or a parent class
37
     *
38
     * @type array
39
     */
40
    protected $packets = [
41
        self::PACKET_STATUS => "\x5C\x73\x74\x61\x74\x75\x73\x5C",
42
    ];
43
44
    /**
45
     * The query protocol used to make the call
46
     *
47
     * @type string
48
     */
49
    protected $protocol = 'gamespy';
50
51
    /**
52
     * String name of this protocol class
53
     *
54
     * @type string
55
     */
56
    protected $name = 'gamespy';
57
58
    /**
59
     * Longer string name of this protocol class
60
     *
61
     * @type string
62
     */
63
    protected $name_long = "GameSpy Server";
64
65
    /**
66
     * The client join link
67
     *
68
     * @type string
69
     */
70
    protected $join_link = null;
71
72
    /**
73
     * Process the response for this protocol
74
     *
75
     * @return array
76
     * @throws Exception
77
     */
78 11
    public function processResponse()
79
    {
80
        // Holds the processed packets so we can sort them in case they come in an unordered
81 11
        $processed = [];
82
83
        // Iterate over the packets
84 11
        foreach ($this->packets_response as $response) {
85
            // Check to see if we had a preg_match error
86 11
            if (($match = preg_match("#^(.*)\\\\queryid\\\\([^\\\\]+)(\\\\|$)#", $response, $matches)) === false
87 11
                || $match != 1
88
            ) {
89 2
                throw new Exception(__METHOD__ . " An error occurred while parsing the packets for 'queryid'");
90
            }
91
92
            // Multiply so we move the decimal point out of the way, if there is one
93 9
            $key = (int)(floatval($matches[2]) * 1000);
94
95
            // Add this packet to the processed
96 9
            $processed[$key] = $matches[1];
97
        }
98
99
        // Sort the new array to make sure the keys (query ids) are in the proper order
100 9
        ksort($processed, SORT_NUMERIC);
101
102
        // Create buffer and offload processing
103 9
        return $this->processStatus(new Buffer(implode('', $processed)));
104
    }
105
106
    /*
107
     * Internal methods
108
     */
109
110
    /**
111
     * Handle processing the status buffer
112
     *
113
     * @param Buffer $buffer
114
     *
115
     * @return array
116
     */
117 9
    protected function processStatus(Buffer $buffer)
118
    {
119
        // Set the result to a new result instance
120 9
        $result = new Result();
121
122
        // By default dedicted
123 9
        $result->add('dedicated', 1);
124
125
        // Lets peek and see if the data starts with a \
126 9
        if ($buffer->lookAhead(1) == '\\') {
127
            // Burn the first one
128 9
            $buffer->skip(1);
129
        }
130
131
        // Explode the data
132 9
        $data = explode('\\', $buffer->getBuffer());
133
134
        // No longer needed
135 9
        unset($buffer);
136
137
        // Init some vars
138 9
        $numPlayers = 0;
139 9
        $numTeams = 0;
140
141 9
        $itemCount = count($data);
142
143 9
        if ($itemCount >= 1)
144
        {
145 9
            return $result->fetch();
146
        }
147
148
        // Now lets loop the array
149
        for ($x = 0; $x < $itemCount; $x += 2) {
150
            // Set some local vars
151
            $key = $data[$x];
152
            $val = $data[$x + 1];
153
154
            // Check for <variable>_<count> variable (i.e players)
155
            if (($suffix = strrpos($key, '_')) !== false && is_numeric(substr($key, $suffix + 1))) {
156
                // See if this is a team designation
157
                if (substr($key, 0, $suffix) == 'teamname') {
158
                    $result->addTeam('teamname', $val);
159
                    $numTeams++;
160
                } else {
161
                    // Its a player
162
                    if (substr($key, 0, $suffix) == 'playername') {
163
                        $numPlayers++;
164
                    }
165
                    $result->addPlayer(substr($key, 0, $suffix), utf8_encode($val));
166
                }
167
            } else {
168
                // Regular variable so just add the value.
169
                $result->add($key, $val);
170
            }
171
        }
172
173
        // Add the player and team count
174
        $result->add('num_players', $numPlayers);
175
        $result->add('num_teams', $numTeams);
176
177
        // Unset some stuff to free up memory
178
        unset($data, $key, $val, $suffix, $x, $itemCount);
179
180
        // Return the result
181
        return $result->fetch();
182
    }
183
}
184