Passed
Pull Request — v3 (#660)
by Austin
03:20 queued 24s
created

Stationeers::beforeSend()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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\Result;
23
use GameQ\Server;
24
25
/**
26
 * Stationeers Protocol Class
27
 *
28
 * This protocol uses a server list from a JSON response to find the server and parse the server's status information
29
 *
30
 * @author Austin Bischoff <[email protected]>
31
 */
32
class Stationeers extends Http
33
{
34
    /**
35
     * The host (address) of the server to query to get the list of servers
36
     */
37
    const SERVER_LIST_HOST = '40.82.200.175';
38
39
    /**
40
     * The port of the server to query to get the list of servers
41
     */
42
    const SERVER_LIST_PORT = 8081;
43
44
    /**
45
     * Holds the real ip so we can overwrite it back
46
     *
47
     * @var string
48
     */
49
    protected $realIp = null;
50
51
    /**
52
     * Holds the real port so we can overwrite it back
53
     *
54
     * @var int
55
     */
56
    protected $realPortQuery = null;
57
58
    /**
59
     * Packets to send
60
     *
61
     * @var array
62
     */
63
    protected $packets = [
64
        self::PACKET_STATUS => "GET /list HTTP/1.0\r\nAccept: */*\r\n\r\n",
65
    ];
66
67
    /**
68
     * The protocol being used
69
     *
70
     * @var string
71
     */
72
    protected $protocol = 'stationeers';
73
74
    /**
75
     * String name of this protocol class
76
     *
77
     * @var string
78
     */
79
    protected $name = 'stationeers';
80
81
    /**
82
     * Longer string name of this protocol class
83
     *
84
     * @var string
85
     */
86
    protected $name_long = "Stationeers";
87
88
    /**
89
     * The client join link
90
     *
91
     * @type string
92
     */
93
    protected $join_link = "";
94
95
    /**
96
     * Normalize some items
97
     *
98
     * @var array
99
     */
100
    protected $normalize = [
101
        // General
102
        'general' => [
103
            // target       => source
104
            'dedicated'  => 'dedicated',
105
            'hostname'   => 'hostname',
106
            'mapname'    => 'map',
107
            'maxplayers' => 'maxplayers',
108
            'numplayers' => 'numplayers',
109
            'password'   => 'password',
110
        ],
111
    ];
112
113
    /**
114
     * Handle changing the call to call a central server rather than the server directly
115
     *
116
     * @param Server $server
117
     *
118
     * @return void
119
     */
120 12
    public function beforeSend(Server $server)
121
    {
122
        // Save the passed IP information so we can use it later for the response
123 12
        $this->realIp = $server->ip;
124 12
        $this->realPortQuery = $server->port_query;
125
126
        // Override the existing settings with the query host information
127 12
        $server->ip = self::SERVER_LIST_HOST;
128 12
        $server->port_query = self::SERVER_LIST_PORT;
129 4
    }
130
131
    /**
132
     * Process the response
133
     *
134
     * @return array
135
     * @throws Exception
136
     */
137 12
    public function processResponse()
138
    {
139 12
        if (empty($this->packets_response)) {
140
            return [];
141
        }
142
143
        // Implode and rip out the JSON
144 12
        preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches);
145
146
        // Return should be JSON, let's validate
147 12
        if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) {
148
            throw new Exception(__METHOD__ . " JSON response from Stationeers protocol is invalid.");
149
        }
150
151
        // By default no server is found
152 12
        $server = null;
153
154
        // Find the server on this list by iterating over the entire list.
155 12
        foreach ($json->GameSessions as $serverEntry) {
156
            // Server information passed matches an entry on this list
157 12
            if ($serverEntry->Address === $this->realIp && (int)$serverEntry->Port === $this->realPortQuery) {
158 12
                $server = $serverEntry;
159 12
                break;
160
            }
161
        }
162
163
        // No longer needed, be free!
164 12
        unset($matches, $serverEntry, $json);
165
166
        // The server information passed was not found in this host's list
167 12
        if (!$server) {
168
            throw new Exception(sprintf(
169
                '%s Unable to find the server "%s:%d" in the Stationeers server list',
170
                __METHOD__,
171
                $this->realIp,
172
                $this->realPortQuery
173
            ));
174
        }
175
176 12
        $result = new Result();
177
178
        // Server is always dedicated
179 12
        $result->add('dedicated', 1);
180
181
        // Add server items
182 12
        $result->add('hostname', $server->Name);
183 12
        $result->add('gq_address', $server->Address);
184 12
        $result->add('gq_port_query', $server->Port);
185 12
        $result->add('version', $server->Version);
186 12
        $result->add('map', $server->MapName);
187 12
        $result->add('uptime', $server->UpTime);
188 12
        $result->add('password', (int)$server->Password);
189 12
        $result->add('numplayers', $server->Players);
190 12
        $result->add('maxplayers', $server->MaxPlayers);
191 12
        $result->add('type', $server->Type);
192
193 12
        unset($server);
194
195 12
        return $result->fetch();
196
    }
197
}
198