PocketMine-MP 5.18.2 git-00e39821f06a4b6d728d35053c2621dbb19369ff
scan.php
1<?php
2
3declare(strict_types=1);
4
12
13require dirname(__DIR__) . '/vendor/autoload.php';
14
15if(count($argv) === 3){
16 $broadcastAddress = $argv[1];
17 $port = (int) $argv[2];
18}else{
19 echo "Usage: php scan.php <broadcast address> <port>" . PHP_EOL;
20 exit(1);
21}
22
23if(str_contains($broadcastAddress, ".")){
24 $bindAddress = new InternetAddress("0.0.0.0", 0, 4);
25}else{
26 $bindAddress = new InternetAddress("::", 0, 6);
27}
28
29$socket = new ServerSocket($bindAddress);
30$socket->enableBroadcast();
31$clientId = mt_rand(0, Limits::INT32_MAX);
32\GlobalLogger::get()->info("Listening on " . $bindAddress);
33\GlobalLogger::get()->info("Press CTRL+C to stop");
34
35function sendPing(ServerSocket $socket, string $broadcastAddress, int $port, int $clientId) : void{
36 $ping = new UnconnectedPing();
37 $ping->clientId = $clientId;
38 $ping->sendPingTime = intdiv(hrtime(true), 1_000_000);
39
40 $serializer = new PacketSerializer();
41 $ping->encode($serializer);
42 $socket->writePacket($serializer->getBuffer(), $broadcastAddress, $port);
43}
44sendPing($socket, $broadcastAddress, $port, $clientId);
45
46socket_set_option($socket->getSocket(), SOL_SOCKET, SO_RCVTIMEO, ["sec" => 1, "usec" => 0]);
47while(true){ //@phpstan-ignore-line
48 try{
49 $pong = $socket->readPacket($serverIp, $serverPort);
50 if($pong !== null && ord($pong[0]) === MessageIdentifiers::ID_UNCONNECTED_PONG){
51 \GlobalLogger::get()->info("Pong received from $serverIp:$serverPort: " . $pong);
52 }
53 }catch(SocketException $e){
54 if($e->getCode() === SOCKET_ETIMEDOUT){
55 sendPing($socket, $broadcastAddress, $port, $clientId);
56 }
57 }
58}