diff --git a/src/Server.php b/src/Server.php index 38f192f5f..24c1a509c 100644 --- a/src/Server.php +++ b/src/Server.php @@ -59,6 +59,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; +use pocketmine\network\query\QueryInfo; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; @@ -271,8 +272,8 @@ class Server{ */ private $uniquePlayers = []; - /** @var QueryRegenerateEvent */ - private $queryRegenerateTask; + /** @var QueryInfo */ + private $queryInfo; /** @var Config */ private $properties; @@ -1023,7 +1024,7 @@ class Server{ $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); - $this->queryRegenerateTask = new QueryRegenerateEvent($this); + $this->queryInfo = new QueryInfo($this); register_shutdown_function([$this, "crashDump"]); @@ -1424,10 +1425,10 @@ class Server{ } /** - * @return QueryRegenerateEvent + * @return QueryInfo */ public function getQueryInformation(){ - return $this->queryRegenerateTask; + return $this->queryInfo; } /** @@ -1680,7 +1681,9 @@ class Server{ $this->currentTPS = 20; $this->currentUse = 0; - ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); + $queryRegenerateEvent = new QueryRegenerateEvent(new QueryInfo($this)); + $queryRegenerateEvent->call(); + $this->queryInfo = $queryRegenerateEvent->getQueryInfo(); $this->network->updateName(); $this->network->resetStatistics(); diff --git a/src/event/server/QueryRegenerateEvent.php b/src/event/server/QueryRegenerateEvent.php index 3b6a19c2a..5bf879f94 100644 --- a/src/event/server/QueryRegenerateEvent.php +++ b/src/event/server/QueryRegenerateEvent.php @@ -23,225 +23,17 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\player\Player; -use pocketmine\plugin\Plugin; -use pocketmine\Server; -use pocketmine\utils\Binary; -use function chr; -use function count; -use function str_replace; -use function substr; +use pocketmine\network\query\QueryInfo; class QueryRegenerateEvent extends ServerEvent{ - public const GAME_ID = "MINECRAFTPE"; - - /** @var string */ - private $serverName; - /** @var bool */ - private $listPlugins; - /** @var Plugin[] */ - private $plugins; - /** @var Player[] */ - private $players; - - /** @var string */ - private $gametype; - /** @var string */ - private $version; - /** @var string */ - private $server_engine; - /** @var string */ - private $map; - /** @var int */ - private $numPlayers; - /** @var int */ - private $maxPlayers; - /** @var string */ - private $whitelist; - /** @var int */ - private $port; - /** @var string */ - private $ip; - - /** - * @var string[] - * @phpstan-var array - */ - private $extraData = []; - - /** @var string|null */ - private $longQueryCache = null; - /** @var string|null */ - private $shortQueryCache = null; - - public function __construct(Server $server){ - $this->serverName = $server->getMotd(); - $this->listPlugins = $server->getProperty("settings.query-plugins", true); - $this->plugins = $server->getPluginManager()->getPlugins(); - $this->players = $server->getOnlinePlayers(); - - $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; - $this->version = $server->getVersion(); - $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); - $world = $server->getWorldManager()->getDefaultWorld(); - $this->map = $world === null ? "unknown" : $world->getDisplayName(); - $this->numPlayers = count($this->players); - $this->maxPlayers = $server->getMaxPlayers(); - $this->whitelist = $server->hasWhitelist() ? "on" : "off"; - $this->port = $server->getPort(); - $this->ip = $server->getIp(); + /** @var QueryInfo */ + private $queryInfo; + public function __construct(QueryInfo $queryInfo){ + $this->queryInfo = $queryInfo; } - private function destroyCache() : void{ - $this->longQueryCache = null; - $this->shortQueryCache = null; - } - - public function getServerName() : string{ - return $this->serverName; - } - - public function setServerName(string $serverName) : void{ - $this->serverName = $serverName; - $this->destroyCache(); - } - - public function canListPlugins() : bool{ - return $this->listPlugins; - } - - public function setListPlugins(bool $value) : void{ - $this->listPlugins = $value; - $this->destroyCache(); - } - - /** - * @return Plugin[] - */ - public function getPlugins() : array{ - return $this->plugins; - } - - /** - * @param Plugin[] $plugins - */ - public function setPlugins(array $plugins) : void{ - $this->plugins = $plugins; - $this->destroyCache(); - } - - /** - * @return Player[] - */ - public function getPlayerList() : array{ - return $this->players; - } - - /** - * @param Player[] $players - */ - public function setPlayerList(array $players) : void{ - $this->players = $players; - $this->destroyCache(); - } - - public function getPlayerCount() : int{ - return $this->numPlayers; - } - - public function setPlayerCount(int $count) : void{ - $this->numPlayers = $count; - $this->destroyCache(); - } - - public function getMaxPlayerCount() : int{ - return $this->maxPlayers; - } - - public function setMaxPlayerCount(int $count) : void{ - $this->maxPlayers = $count; - $this->destroyCache(); - } - - public function getWorld() : string{ - return $this->map; - } - - public function setWorld(string $world) : void{ - $this->map = $world; - $this->destroyCache(); - } - - /** - * Returns the extra Query data in key => value form - * - * @return string[] - * @phpstan-return array - */ - public function getExtraData() : array{ - return $this->extraData; - } - - /** - * @param string[] $extraData - * @phpstan-param array $extraData - */ - public function setExtraData(array $extraData) : void{ - $this->extraData = $extraData; - $this->destroyCache(); - } - - public function getLongQuery() : string{ - if($this->longQueryCache !== null){ - return $this->longQueryCache; - } - $query = ""; - - $plist = $this->server_engine; - if(count($this->plugins) > 0 and $this->listPlugins){ - $plist .= ":"; - foreach($this->plugins as $p){ - $d = $p->getDescription(); - $plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";"; - } - $plist = substr($plist, 0, -1); - } - - $KVdata = [ - "splitnum" => chr(128), - "hostname" => $this->serverName, - "gametype" => $this->gametype, - "game_id" => self::GAME_ID, - "version" => $this->version, - "server_engine" => $this->server_engine, - "plugins" => $plist, - "map" => $this->map, - "numplayers" => $this->numPlayers, - "maxplayers" => $this->maxPlayers, - "whitelist" => $this->whitelist, - "hostip" => $this->ip, - "hostport" => $this->port - ]; - - foreach($KVdata as $key => $value){ - $query .= $key . "\x00" . $value . "\x00"; - } - - foreach($this->extraData as $key => $value){ - $query .= $key . "\x00" . $value . "\x00"; - } - - $query .= "\x00\x01player_\x00\x00"; - foreach($this->players as $player){ - $query .= $player->getName() . "\x00"; - } - $query .= "\x00"; - - return $this->longQueryCache = $query; - } - - public function getShortQuery() : string{ - return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); + public function getQueryInfo() : QueryInfo{ + return $this->queryInfo; } } diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php new file mode 100644 index 000000000..975bfa714 --- /dev/null +++ b/src/network/query/QueryInfo.php @@ -0,0 +1,248 @@ + + */ + private $extraData = []; + + /** @var string|null */ + private $longQueryCache = null; + /** @var string|null */ + private $shortQueryCache = null; + + public function __construct(Server $server){ + $this->serverName = $server->getMotd(); + $this->listPlugins = $server->getProperty("settings.query-plugins", true); + $this->plugins = $server->getPluginManager()->getPlugins(); + $this->players = $server->getOnlinePlayers(); + + $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; + $this->version = $server->getVersion(); + $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); + $world = $server->getWorldManager()->getDefaultWorld(); + $this->map = $world === null ? "unknown" : $world->getDisplayName(); + $this->numPlayers = count($this->players); + $this->maxPlayers = $server->getMaxPlayers(); + $this->whitelist = $server->hasWhitelist() ? "on" : "off"; + $this->port = $server->getPort(); + $this->ip = $server->getIp(); + + } + + private function destroyCache() : void{ + $this->longQueryCache = null; + $this->shortQueryCache = null; + } + + public function getServerName() : string{ + return $this->serverName; + } + + public function setServerName(string $serverName) : void{ + $this->serverName = $serverName; + $this->destroyCache(); + } + + public function canListPlugins() : bool{ + return $this->listPlugins; + } + + public function setListPlugins(bool $value) : void{ + $this->listPlugins = $value; + $this->destroyCache(); + } + + /** + * @return Plugin[] + */ + public function getPlugins() : array{ + return $this->plugins; + } + + /** + * @param Plugin[] $plugins + */ + public function setPlugins(array $plugins) : void{ + $this->plugins = $plugins; + $this->destroyCache(); + } + + /** + * @return Player[] + */ + public function getPlayerList() : array{ + return $this->players; + } + + /** + * @param Player[] $players + */ + public function setPlayerList(array $players) : void{ + $this->players = $players; + $this->destroyCache(); + } + + public function getPlayerCount() : int{ + return $this->numPlayers; + } + + public function setPlayerCount(int $count) : void{ + $this->numPlayers = $count; + $this->destroyCache(); + } + + public function getMaxPlayerCount() : int{ + return $this->maxPlayers; + } + + public function setMaxPlayerCount(int $count) : void{ + $this->maxPlayers = $count; + $this->destroyCache(); + } + + public function getWorld() : string{ + return $this->map; + } + + public function setWorld(string $world) : void{ + $this->map = $world; + $this->destroyCache(); + } + + /** + * Returns the extra Query data in key => value form + * + * @return string[] + * @phpstan-return array + */ + public function getExtraData() : array{ + return $this->extraData; + } + + /** + * @param string[] $extraData + * + * @phpstan-param array $extraData + */ + public function setExtraData(array $extraData) : void{ + $this->extraData = $extraData; + $this->destroyCache(); + } + + public function getLongQuery() : string{ + if($this->longQueryCache !== null){ + return $this->longQueryCache; + } + $query = ""; + + $plist = $this->server_engine; + if(count($this->plugins) > 0 and $this->listPlugins){ + $plist .= ":"; + foreach($this->plugins as $p){ + $d = $p->getDescription(); + $plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";"; + } + $plist = substr($plist, 0, -1); + } + + $KVdata = [ + "splitnum" => chr(128), + "hostname" => $this->serverName, + "gametype" => $this->gametype, + "game_id" => self::GAME_ID, + "version" => $this->version, + "server_engine" => $this->server_engine, + "plugins" => $plist, + "map" => $this->map, + "numplayers" => $this->numPlayers, + "maxplayers" => $this->maxPlayers, + "whitelist" => $this->whitelist, + "hostip" => $this->ip, + "hostport" => $this->port + ]; + + foreach($KVdata as $key => $value){ + $query .= $key . "\x00" . $value . "\x00"; + } + + foreach($this->extraData as $key => $value){ + $query .= $key . "\x00" . $value . "\x00"; + } + + $query .= "\x00\x01player_\x00\x00"; + foreach($this->players as $player){ + $query .= $player->getName() . "\x00"; + } + $query .= "\x00"; + + return $this->longQueryCache = $query; + } + + public function getShortQuery() : string{ + return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); + } +}