Passed
Push — v3 ( 836575...105154 )
by
unknown
02:40
created

Lhmp::processResponse()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 37
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4.026

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 37
ccs 15
cts 17
cp 0.8824
rs 9.7666
cc 4
nc 6
nop 0
crap 4.026
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\Buffer;
22
use GameQ\Exception\Protocol as Exception;
23
use GameQ\Helpers\Str;
24
use GameQ\Protocol;
25
use GameQ\Result;
26
27
/**
28
 * Lost Heaven Protocol class
29
 *
30
 * Reference: http://lh-mp.eu/wiki/index.php/Query_System
31
 *
32
 * @author Austin Bischoff <[email protected]>
33
 */
34
class Lhmp extends Protocol
35
{
36
    /**
37
     * Array of packets we want to look up.
38
     * Each key should correspond to a defined method in this or a parent class
39
     *
40
     * @var array
41
     */
42
    protected $packets = [
43
        self::PACKET_DETAILS => "LHMPo",
44
        self::PACKET_PLAYERS => "LHMPp",
45
    ];
46
47
    /**
48
     * Use the response flag to figure out what method to run
49
     *
50
     * @var array
51
     */
52
    protected $responses = [
53
        "LHMPo" => "processDetails",
54
        "LHMPp" => "processPlayers",
55
    ];
56
57
    /**
58
     * The query protocol used to make the call
59
     *
60
     * @var string
61
     */
62
    protected $protocol = 'lhmp';
63
64
    /**
65
     * String name of this protocol class
66
     *
67
     * @var string
68
     */
69
    protected $name = 'lhmp';
70
71
    /**
72
     * Longer string name of this protocol class
73
     *
74
     * @var string
75
     */
76
    protected $name_long = "Lost Heaven";
77
78
    /**
79
     * query_port = client_port + 1
80
     *
81
     * @var int
82
     */
83
    protected $port_diff = 1;
84
85
    /**
86
     * Normalize settings for this protocol
87
     *
88
     * @var array
89
     */
90
    protected $normalize = [
91
        // General
92
        'general' => [
93
            // target       => source
94
            'gametype'   => 'gamemode',
95
            'hostname'   => 'servername',
96
            'mapname'    => 'mapname',
97
            'maxplayers' => 'maxplayers',
98
            'numplayers' => 'numplayers',
99
            'password'   => 'password',
100
        ],
101
        // Individual
102
        'player'  => [
103
            'name'  => 'name',
104
        ],
105
    ];
106
107
    /**
108
     * Process the response
109
     *
110
     * @return array
111
     * @throws \GameQ\Exception\Protocol
112
     */
113 12
    public function processResponse()
114
    {
115
        // Will hold the packets after sorting
116 12
        $packets = [];
117
118
        // We need to pre-sort these for split packets so we can do extra work where needed
119 12
        foreach ($this->packets_response as $response) {
120 12
            $buffer = new Buffer($response);
121
122
            // Pull out the header
123 12
            $header = $buffer->read(5);
124
125
            // Add the packet to the proper section, we will combine later
126 12
            $packets[$header][] = $buffer->getBuffer();
127
        }
128
129 12
        unset($buffer);
130
131 12
        $results = [];
132
133
        // Now let's iterate and process
134 12
        foreach ($packets as $header => $packetGroup) {
135
            // Figure out which packet response this is
136 12
            if (!array_key_exists($header, $this->responses)) {
137 12
                throw new Exception(__METHOD__ . " response type '{$header}' is not valid");
138
            }
139
140
            // Now we need to call the proper method
141 12
            $results = array_merge(
142 12
                $results,
143 12
                call_user_func_array([$this, $this->responses[$header]], [new Buffer(implode($packetGroup))])
144 12
            );
145
        }
146
147
        unset($packets);
148
149
        return $results;
150
    }
151
152
    // Internal methods
153
154
    /**
155
     * Handles processing the details data into a usable format
156
     *
157
     * @param Buffer $buffer
158
     * @return array
159
     * @throws Exception
160
     * @throws \GameQ\Exception\Protocol
161
     */
162
    protected function processDetails(Buffer $buffer)
163
    {
164
        // Set the result to a new result instance
165
        $result = new Result();
166
167
        $result->add('protocol', $buffer->readString());
168
        $result->add('password', $buffer->readString());
169
        $result->add('numplayers', $buffer->readInt16());
170
        $result->add('maxplayers', $buffer->readInt16());
171
        $result->add('servername', Str::isoToUtf8($buffer->readPascalString()));
172
        $result->add('gamemode', $buffer->readPascalString());
173
        $result->add('website', Str::isoToUtf8($buffer->readPascalString()));
174
        $result->add('mapname', Str::isoToUtf8($buffer->readPascalString()));
175
176
        unset($buffer);
177
178
        return $result->fetch();
179
    }
180
181
    /**
182
     * Handles processing the player data into a usable format
183
     *
184
     * @param Buffer $buffer
185
     * @return array
186
     * @throws \GameQ\Exception\Protocol
187
     */
188 12
    protected function processPlayers(Buffer $buffer)
189
    {
190
        // Set the result to a new result instance
191 12
        $result = new Result();
192
193
        // Get the number of players
194 12
        $result->add('numplayers', $buffer->readInt16());
195
196
        // Parse players
197 12
        while ($buffer->getLength()) {
198
            // Player id
199
            if (($id = $buffer->readInt16()) !== 0) {
200
                // Add the results
201
                $result->addPlayer('id', $id);
202
                $result->addPlayer('name', Str::isoToUtf8($buffer->readPascalString()));
203
            }
204
        }
205
206 12
        unset($buffer, $id);
207
208 12
        return $result->fetch();
209
    }
210
}
211