Merge pull request #2166 from PocketMine/query-event-implementation

Query event implementation
This commit is contained in:
Shoghi Cervantes 2014-10-07 11:46:55 +02:00
commit e346d245e2
4 changed files with 237 additions and 45 deletions

View File

@ -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";

View File

@ -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");
}
/**

View File

@ -0,0 +1,222 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\event\server;
use pocketmine\event;
use pocketmine\Server;
use pocketmine\utils\Binary;
class QueryRegenerateEvent extends ServerEvent{
public static $handlerList = null;
const GAME_ID = "MINECRAFTPE";
private $timeout;
private $serverName;
private $listPlugins;
/** @var \pocketmine\plugin\Plugin[] */
private $plugins;
/** @var \pocketmine\Player[] */
private $players;
private $gametype;
private $version;
private $server_engine;
private $map;
private $numPlayers;
private $maxPlayers;
private $whitelist;
private $port;
private $ip;
private $extraData = [];
public function __construct(Server $server, $timeout = 5){
$this->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";
}
}

View File

@ -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;