1
|
|
|
<?php |
2
|
|
|
namespace PHPDaemon\Clients\Valve; |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* @package NetworkClients |
6
|
|
|
* @subpackage HLClient |
7
|
|
|
* @author Vasily Zorin <[email protected]> |
8
|
|
|
* @link https://developer.valvesoftware.com/wiki/Server_queries |
9
|
|
|
*/ |
10
|
|
|
class Pool extends \PHPDaemon\Network\Client |
11
|
|
|
{ |
12
|
|
|
const A2S_INFO = "\x54"; |
13
|
|
|
const S2A_INFO = "\x49"; |
14
|
|
|
const S2A_INFO_SOURCE = "\x6d"; |
15
|
|
|
const A2S_PLAYER = "\x55"; |
16
|
|
|
const S2A_PLAYER = "\x44"; |
17
|
|
|
const A2S_SERVERQUERY_GETCHALLENGE = "\x57"; |
18
|
|
|
const S2A_SERVERQUERY_GETCHALLENGE = "\x41"; |
19
|
|
|
const A2A_PING = "\x69"; |
20
|
|
|
const S2A_PONG = "\x6A"; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Sends echo-request |
24
|
|
|
* @param string $addr Address |
25
|
|
|
* @param callable $cb Callback |
26
|
|
|
* @callback $cb ( ) |
27
|
|
|
* @return void |
28
|
|
|
*/ |
29
|
|
|
public function ping($addr, $cb) |
30
|
|
|
{ |
31
|
|
|
$e = explode(':', $addr); |
32
|
|
|
$this->getConnection('valve://[udp:' . $e[0] . ']' . (isset($e[1]) ? ':' . $e[1] : '') . '/ping', |
33
|
|
|
function ($conn) use ($cb) { |
34
|
|
|
if (!$conn->connected) { |
35
|
|
|
$cb($conn, false); |
36
|
|
|
return; |
37
|
|
|
} |
38
|
|
|
$mt = microtime(true); |
39
|
|
|
$conn->request('ping', null, function ($conn, $success) use ($mt, $cb) { |
40
|
|
|
$cb($conn, $success ? (microtime(true) - $mt) : false); |
41
|
|
|
}); |
42
|
|
|
}); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Sends a request of type 'info' |
47
|
|
|
* @param string $addr Address |
48
|
|
|
* @param callable $cb Callback |
49
|
|
|
* @callback $cb ( ) |
50
|
|
|
* @return void |
51
|
|
|
*/ |
52
|
|
|
public function requestInfo($addr, $cb) |
53
|
|
|
{ |
54
|
|
|
$this->request($addr, 'info', null, $cb); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Sends a request |
59
|
|
|
* @param string $addr Address |
60
|
|
|
* @param string $type Type of request |
61
|
|
|
* @param string $data Data |
62
|
|
|
* @param callable $cb Callback |
63
|
|
|
* @callback $cb ( ) |
64
|
|
|
* @return void |
65
|
|
|
*/ |
66
|
|
|
public function request($addr, $type, $data, $cb) |
67
|
|
|
{ |
68
|
|
|
$e = explode(':', $addr); |
69
|
|
|
$this->getConnection('valve://[udp:' . $e[0] . ']' . (isset($e[1]) ? ':' . $e[1] : '') . '/', |
70
|
|
|
function ($conn) use ($cb, $addr, $data, $type) { |
71
|
|
|
if (!$conn->connected) { |
72
|
|
|
$cb($conn, false); |
73
|
|
|
return; |
74
|
|
|
} |
75
|
|
|
$conn->request($type, $data, $cb); |
76
|
|
|
}); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Sends a request of type 'players' |
81
|
|
|
* @param string $addr Address |
82
|
|
|
* @param callable $cb Callback |
83
|
|
|
* @callback $cb ( ) |
84
|
|
|
* @return void |
85
|
|
|
*/ |
86
|
|
View Code Duplication |
public function requestPlayers($addr, $cb) |
|
|
|
|
87
|
|
|
{ |
88
|
|
|
$this->request($addr, 'challenge', null, function ($conn, $result) use ($cb) { |
89
|
|
|
if (is_array($result)) { |
90
|
|
|
$cb($conn, $result); |
91
|
|
|
return; |
92
|
|
|
} |
93
|
|
|
$conn->request('players', $result, $cb); |
94
|
|
|
}); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Setting default config options |
99
|
|
|
* Overriden from NetworkClient::getConfigDefaults |
100
|
|
|
* @return array|bool |
101
|
|
|
*/ |
102
|
|
|
protected function getConfigDefaults() |
103
|
|
|
{ |
104
|
|
|
return [ |
105
|
|
|
/* [string|array] Default servers */ |
106
|
|
|
'servers' => '127.0.0.1', |
107
|
|
|
|
108
|
|
|
/* [integer] Default port */ |
109
|
|
|
'port' => 27015, |
110
|
|
|
|
111
|
|
|
/* [integer] Maximum connections per server */ |
112
|
|
|
'maxconnperserv' => 32, |
113
|
|
|
]; |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.