diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 7ed5cbbd2..b227bd985 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -73,7 +73,7 @@ namespace pocketmine { use raklib\RakLib; const VERSION = "Alpha_1.4dev"; - const API_VERSION = "1.4.1"; + const API_VERSION = "1.5.0"; const CODENAME = "絶好(Zekkou)ケーキ(Cake)"; const MINECRAFT_VERSION = "v0.9.5 alpha"; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 7a377ad39..912d8ae93 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -290,14 +290,14 @@ class Server{ * @return string */ public function getIp(){ - return $this->getConfigString("server-ip", ""); + return $this->getConfigString("server-ip", "0.0.0.0"); } /** * @return string */ public function getServerName(){ - return $this->getConfigString("server-name", "Unknown server"); + return $this->getConfigString("motd", "Unknown server"); } /** diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php new file mode 100644 index 000000000..2d3fe6ea2 --- /dev/null +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -0,0 +1,222 @@ +timeout = $timeout; + $this->serverName = $server->getServerName(); + $this->listPlugins = $server->getProperty("settings.query-plugins", true); + $this->plugins = $server->getPluginManager()->getPlugins(); + $this->players = []; + foreach($server->getOnlinePlayers() as $player){ + if($player->getName() != "" and $player->isConnected()){ + $this->players[] = $player; + } + } + + $this->gametype = ($server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP"; + $this->version = $server->getVersion(); + $this->server_engine = $server->getName() ." ". $server->getPocketMineVersion(); + $this->map = $server->getDefaultLevel() === null ? "unknown" : $server->getDefaultLevel()->getName(); + $this->numPlayers = count($this->players); + $this->maxPlayers = $server->getMaxPlayers(); + $this->whitelist = $server->hasWhitelist() ? "on" : "off"; + $this->port = $server->getPort(); + $this->ip = $server->getIp(); + + } + + /** + * Gets the min. timeout for Query Regeneration + * + * @return int + */ + public function getTimeout(){ + return $this->timeout; + } + + public function setTimeout($timeout){ + $this->timeout = $timeout; + } + + public function getServerName(){ + return $this->serverName; + } + + public function setServerName($serverName){ + $this->serverName = $serverName; + } + + public function canListPlugins(){ + return $this->listPlugins; + } + + public function setListPlugins($value){ + $this->listPlugins = (bool) $value; + } + + /** + * @return \pocketmine\plugin\Plugin[] + */ + public function getPlugins(){ + return $this->plugins; + } + + /** + * @param \pocketmine\plugin\Plugin[] $plugins + */ + public function setPlugins(array $plugins){ + $this->plugins = $plugins; + } + + /** + * @return \pocketmine\Player[] + */ + public function getPlayerList(){ + return $this->players; + } + + /** + * @param \pocketmine\Player[] $players + */ + public function setPlayerList(array $players){ + $this->players = $players; + } + + public function getPlayerCount(){ + return $this->numPlayers; + } + + public function setPlayerCount($count){ + $this->numPlayers = (int) $count; + } + + public function getMaxPlayerCount(){ + return $this->maxPlayers; + } + + public function setMaxPlayerCount($count){ + $this->maxPlayers = (int) $count; + } + + public function getWorld(){ + return $this->map; + } + + public function setWorld($world){ + $this->map = (string) $world; + } + + /** + * Returns the extra Query data in key => value form + * + * @return array + */ + public function getExtraData(){ + return $this->extraData; + } + + public function setExtraData(array $extraData){ + $this->extraData = $extraData; + } + + public function getLongQuery(){ + $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 $query; + } + + public function getShortQuery(){ + return $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"; + } + +} \ No newline at end of file diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index ade5ff79d..155e6c1a9 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -25,12 +25,13 @@ */ namespace pocketmine\network\query; +use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\Server; use pocketmine\utils\Binary; use pocketmine\utils\Utils; class QueryHandler{ - private $server, $lastToken, $token, $longData, $timeout; + private $server, $lastToken, $token, $longData, $shortData, $timeout; const HANDSHAKE = 9; const STATISTICS = 0; @@ -57,43 +58,10 @@ class QueryHandler{ } public function regenerateInfo(){ - $str = ""; - $plist = $this->server->getName() . " " . $this->server->getPocketMineVersion(); - $pl = $this->server->getPluginManager()->getPlugins(); - if(count($pl) > 0 and $this->server->getProperty("settings.query-plugins", true) === true){ - $plist .= ":"; - foreach($pl 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->server->getServerName(), - "gametype" => ($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP", - "game_id" => "MINECRAFTPE", - "version" => $this->server->getVersion(), - "server_engine" => $this->server->getName() . " " . $this->server->getPocketMineVersion(), - "plugins" => $plist, - "map" => $this->server->getDefaultLevel() === null ? "unknown" : $this->server->getDefaultLevel()->getName(), - "numplayers" => count($this->server->getOnlinePlayers()), - "maxplayers" => $this->server->getMaxPlayers(), - "whitelist" => $this->server->hasWhitelist() === true ? "on" : "off", - "hostport" => $this->server->getPort() - ]; - foreach($KVdata as $key => $value){ - $str .= $key . "\x00" . $value . "\x00"; - } - $str .= "\x00\x01player_\x00\x00"; - foreach($this->server->getOnlinePlayers() as $player){ - if($player->getName() != ""){ - $str .= $player->getName() . "\x00"; - } - } - $str .= "\x00"; - $this->longData = $str; - $this->timeout = microtime(true) + 5; + $this->server->getPluginManager()->callEvent($ev = new QueryRegenerateEvent($this->server, 5)); + $this->longData = $ev->getLongQuery(); + $this->shortData = $ev->getShortQuery(); + $this->timeout = microtime(true) + $ev->getTimeout(); } public function regenerateToken(){ @@ -127,13 +95,15 @@ class QueryHandler{ } $reply = chr(self::STATISTICS); $reply .= Binary::writeInt($sessionID); + + if($this->timeout < microtime(true)){ + $this->regenerateInfo(); + } + if(strlen($payload) === 8){ - if($this->timeout < microtime(true)){ - $this->regenerateInfo(); - } $reply .= $this->longData; }else{ - $reply .= $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . ($this->server->getDefaultLevel() === null ? "unknown" : $this->server->getDefaultLevel()->getName()) . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Binary::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00"; + $reply .= $this->shortData; } $this->server->sendPacket($address, $port, $reply); break;