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: namespace GameQ\Protocols;
19:
20: use GameQ\Exception\Protocol as Exception;
21: use GameQ\Result;
22: use GameQ\Server;
23:
24: /**
25: * Grand Theft Auto Network Protocol Class
26: * https://stats.gtanet.work/
27: *
28: * Result from this call should be a header + JSON response
29: *
30: * References:
31: * - https://master.gtanet.work/apiservers
32: *
33: * @author Austin Bischoff <austin@codebeard.com>
34: */
35: class Gtan extends Http
36: {
37: /**
38: * Packets to send
39: *
40: * @var array
41: */
42: protected $packets = [
43: //self::PACKET_STATUS => "GET /apiservers HTTP/1.0\r\nHost: master.gtanet.work\r\nAccept: */*\r\n\r\n",
44: self::PACKET_STATUS => "GET /gtan/api.php?ip=%s&raw HTTP/1.0\r\nHost: multiplayerhosting.info\r\nAccept: */*\r\n\r\n",
45: ];
46:
47: /**
48: * Http protocol is SSL
49: *
50: * @var string
51: */
52: protected $transport = self::TRANSPORT_SSL;
53:
54: /**
55: * The protocol being used
56: *
57: * @var string
58: */
59: protected $protocol = 'gtan';
60:
61: /**
62: * String name of this protocol class
63: *
64: * @var string
65: */
66: protected $name = 'gtan';
67:
68: /**
69: * Longer string name of this protocol class
70: *
71: * @var string
72: */
73: protected $name_long = "Grand Theft Auto Network";
74:
75: /**
76: * Holds the real ip so we can overwrite it back
77: *
78: * @var string
79: */
80: protected $realIp = null;
81:
82: protected $realPortQuery = null;
83:
84: /**
85: * Normalize some items
86: *
87: * @var array
88: */
89: protected $normalize = [
90: // General
91: 'general' => [
92: // target => source
93: 'dedicated' => 'dedicated',
94: 'hostname' => 'hostname',
95: 'mapname' => 'map',
96: 'mod' => 'mod',
97: 'maxplayers' => 'maxplayers',
98: 'numplayers' => 'numplayers',
99: 'password' => 'password',
100: ],
101: ];
102:
103: public function beforeSend(Server $server)
104: {
105: // Loop over the packets and update them
106: foreach ($this->packets as $packetType => $packet) {
107: // Fill out the packet with the server info
108: $this->packets[$packetType] = sprintf($packet, $server->ip . ':' . $server->port_query);
109: }
110:
111: $this->realIp = $server->ip;
112: $this->realPortQuery = $server->port_query;
113:
114: // Override the existing settings
115: //$server->ip = 'master.gtanet.work';
116: $server->ip = 'multiplayerhosting.info';
117: $server->port_query = 443;
118: }
119:
120: /**
121: * Process the response
122: *
123: * @return array
124: * @throws Exception
125: */
126: public function processResponse()
127: {
128: // No response, assume offline
129: if (empty($this->packets_response)) {
130: return [
131: 'gq_address' => $this->realIp,
132: 'gq_port_query' => $this->realPortQuery,
133: ];
134: }
135:
136: // Implode and rip out the JSON
137: preg_match('/\{(.*)\}/ms', implode('', $this->packets_response), $matches);
138:
139: // Return should be JSON, let's validate
140: if (!isset($matches[0]) || ($json = json_decode($matches[0])) === null) {
141: throw new Exception("JSON response from Gtan protocol is invalid.");
142: }
143:
144: $result = new Result();
145:
146: // Server is always dedicated
147: $result->add('dedicated', 1);
148:
149: $result->add('gq_address', $this->realIp);
150: $result->add('gq_port_query', $this->realPortQuery);
151:
152: // Add server items
153: $result->add('hostname', $json->ServerName);
154: $result->add('serverversion', $json->ServerVersion);
155: $result->add('map', ((!empty($json->Map)) ? $json->Map : 'Los Santos/Blaine Country'));
156: $result->add('mod', $json->Gamemode);
157: $result->add('password', (int)$json->Passworded);
158: $result->add('numplayers', $json->CurrentPlayers);
159: $result->add('maxplayers', $json->MaxPlayers);
160:
161: return $result->fetch();
162: }
163: }
164: