Passed
Push — v3 ( e623f3...bf0201 )
by
unknown
02:33
created

Lhmp   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Test Coverage

Coverage 55.26%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 55
c 1
b 0
f 0
dl 0
loc 180
ccs 21
cts 38
cp 0.5526
rs 10

3 Methods

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