Mumble   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 44
c 1
b 0
f 0
dl 0
loc 154
ccs 23
cts 23
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A processResponse() 0 33 4
A processChannelsAndUsers() 0 24 6
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\Exception\Protocol as Exception;
22
use GameQ\Protocol;
23
use GameQ\Result;
24
25
/**
26
 * Mumble Protocol class
27
 *
28
 * References:
29
 * https://github.com/edmundask/MurmurQuery - Thanks to skylord123
30
 *
31
 * @author Austin Bischoff <[email protected]>
32
 */
33
class Mumble extends Protocol
34
{
35
    /**
36
     * Array of packets we want to look up.
37
     * Each key should correspond to a defined method in this or a parent class
38
     *
39
     * @var array
40
     */
41
    protected $packets = [
42
        self::PACKET_ALL => "\x6A\x73\x6F\x6E", // JSON packet
43
    ];
44
45
    /**
46
     * The transport mode for this protocol is TCP
47
     *
48
     * @var string
49
     */
50
    protected $transport = self::TRANSPORT_TCP;
51
52
    /**
53
     * The query protocol used to make the call
54
     *
55
     * @var string
56
     */
57
    protected $protocol = 'mumble';
58
59
    /**
60
     * String name of this protocol class
61
     *
62
     * @var string
63
     */
64
    protected $name = 'mumble';
65
66
    /**
67
     * Longer string name of this protocol class
68
     *
69
     * @var string
70
     */
71
    protected $name_long = "Mumble Server";
72
73
    /**
74
     * The client join link
75
     *
76
     * @var string
77
     */
78
    protected $join_link = "mumble://%s:%d/";
79
80
    /**
81
     * 27800 = 64738 - 36938
82
     *
83
     * @var int
84
     */
85
    protected $port_diff = -36938;
86
87
    /**
88
     * Normalize settings for this protocol
89
     *
90
     * @var array
91
     */
92
    protected $normalize = [
93
        // General
94
        'general' => [
95
            'dedicated'  => 'dedicated',
96
            'gametype'   => 'gametype',
97
            'hostname'   => 'name',
98
            'numplayers' => 'numplayers',
99
            'maxplayers' => 'x_gtmurmur_max_users',
100
        ],
101
        // Player
102
        'player'  => [
103
            'name' => 'name',
104
            'ping' => 'tcpPing',
105
            'team' => 'channel',
106
            'time' => 'onlinesecs',
107
        ],
108
        // Team
109
        'team'    => [
110
            'name' => 'name',
111
        ],
112
    ];
113
114
    /**
115
     * Process the response
116
     *
117
     * @return array
118
     * @throws \GameQ\Exception\Protocol
119
     */
120 18
    public function processResponse()
121
    {
122
        // Try to json_decode, make it into an array
123 18
        if (($data = json_decode(implode('', $this->packets_response), true)) === null) {
124 6
            throw new Exception(__METHOD__ . " Unable to decode JSON data.");
125
        }
126
127
        // Set the result to a new result instance
128 12
        $result = new Result();
129
130
        // Always dedicated
131 12
        $result->add('dedicated', 1);
132
133
        // Let's iterate over the response items, there are a lot
134 12
        foreach ($data as $key => $value) {
135
            // Ignore root for now, that is where all of the channel/player info is housed
136 12
            if (in_array($key, ['root'])) {
137 12
                continue;
138
            }
139
140
            // Add them as is
141 12
            $result->add($key, $value);
142
        }
143
144
        // Offload the channel and user parsing
145 12
        $this->processChannelsAndUsers($data['root'], $result);
146
147 12
        unset($data);
148
149
        // Manually set the number of players
150 12
        $result->add('numplayers', count($result->get('players')));
151
152 12
        return $result->fetch();
153
    }
154
155
    // Internal methods
156
157
    /**
158
     * Handles processing the the channels and user info
159
     *
160
     * @param array         $data
161
     * @param \GameQ\Result $result
162
     */
163 12
    protected function processChannelsAndUsers(array $data, Result &$result)
164
    {
165
        // Let's add all of the channel information
166 12
        foreach ($data as $key => $value) {
167
            // We will handle these later
168 12
            if (in_array($key, ['channels', 'users'])) {
169
                // skip
170 12
                continue;
171
            }
172
173
            // Add the channel property as a team
174 12
            $result->addTeam($key, $value);
175
        }
176
177
        // Itereate over the users in this channel
178 12
        foreach ($data['users'] as $user) {
179 12
            foreach ($user as $key => $value) {
180 12
                $result->addPlayer($key, $value);
181
            }
182
        }
183
184
        // Offload more channels to parse
185 12
        foreach ($data['channels'] as $channel) {
186 12
            $this->processChannelsAndUsers($channel, $result);
187
        }
188
    }
189
}
190