diff --git a/src/API/ConsoleAPI.php b/src/API/ConsoleAPI.php index f70ded2e2..9b4ed8c83 100644 --- a/src/API/ConsoleAPI.php +++ b/src/API/ConsoleAPI.php @@ -41,7 +41,6 @@ class ConsoleAPI{ $this->loop->start(); $this->register("help", "Show available commands", array($this, "defaultCommands")); $this->register("status", "Show server TPS and memory usage", array($this, "defaultCommands")); - $this->alias("lag", "status"); $this->register("difficulty", "Changes server difficulty", array($this, "defaultCommands")); $this->register("invisible", "Changes server visibility", array($this, "defaultCommands")); $this->register("say", "Broadcast a message", array($this, "defaultCommands")); @@ -86,7 +85,6 @@ class ConsoleAPI{ } break; case "status": - case "lag": if(!($issuer instanceof Player) and $issuer === "console"){ $this->server->debugInfo(true); } diff --git a/src/API/PlayerAPI.php b/src/API/PlayerAPI.php index 6cfa6bd1c..efd90f4d9 100644 --- a/src/API/PlayerAPI.php +++ b/src/API/PlayerAPI.php @@ -39,6 +39,7 @@ class PlayerAPI{ $this->server->api->console->register("gamemode", "Changes the player gamemode", array($this, "commandHandler")); $this->server->api->console->register("tppos", "Teleports a player to a position", array($this, "commandHandler")); $this->server->api->console->register("tp", "Teleports a player to another player", array($this, "commandHandler")); + $this->server->api->console->register("lag", "Measure your connection lag", array($this, "commandHandler")); $this->server->api->console->alias("suicide", "kill"); } @@ -113,6 +114,13 @@ class PlayerAPI{ public function commandHandler($cmd, $params, $issuer, $alias){ $output = ""; switch($cmd){ + case "lag": + if(!($issuer instanceof Player)){ + $output .= "Please run this command in-game.\n"; + break; + } + $output .= "Lag: ".round($issuer->getLag(), 2)."\n"; + break; case "gamemode": $gm = -1; $player = false; diff --git a/src/Player.php b/src/Player.php index 237c081de..c6dad04ee 100644 --- a/src/Player.php +++ b/src/Player.php @@ -60,6 +60,7 @@ class Player{ public $blocked = true; private $chunksLoaded = array(); private $chunksOrder = array(); + private $lag = array(0, 0); function __construct($clientID, $ip, $port, $MTU){ $this->MTU = $MTU; @@ -528,6 +529,18 @@ class Player{ } return true; } + + public function measureLag(){ + $this->lag[0] = microtime(true) * 1000; + $this->dataPacket(MC_PING, array( + "time" => (int) $this->lag[0], + )); + $this->sendBuffer(); + } + + public function getLag(){ + return $this->lag[1] - $this->lag[0]; + } public function handle($pid, $data){ if($this->connected === true){ @@ -606,11 +619,16 @@ class Player{ switch($data["id"]){ case 0x01: break; + case MC_PONG: + $this->lag[1] = microtime(true) * 1000; + break; case MC_PING: + $t = (int) (microtime(true) * 1000); $this->dataPacket(MC_PONG, array( "ptime" => $data["time"], "time" => (int) (microtime(true) * 1000), )); + $this->sendBuffer(); break; case MC_DISCONNECT: $this->close("client disconnect"); @@ -724,6 +742,7 @@ class Player{ $this->evid[] = $this->server->event("block.change", array($this, "eventHandler")); $this->evid[] = $this->server->event("player.block.place", array($this, "eventHandler")); $this->evid[] = $this->server->event("tile.container.slot", array($this, "eventHandler")); + $this->server->schedule(40, array($this, "measureLag"), array(), true); break; case MC_READY: if($this->loggedIn === false){ diff --git a/src/constants/ProtocolInfo.php b/src/constants/ProtocolInfo.php index 8c24f2b7d..ef02f24fa 100644 --- a/src/constants/ProtocolInfo.php +++ b/src/constants/ProtocolInfo.php @@ -97,7 +97,7 @@ define("MC_ADVENTURE_SETTINGS", 0xb6); class Protocol{ public static $dataName = array( - MC_KEEP_ALIVE => "Keep Alive", + MC_PING => "Ping", MC_CLIENT_CONNECT => "Client Connect", MC_SERVER_HANDSHAKE => "Server Handshake",