Fixed basic stuff around

This commit is contained in:
Shoghi Cervantes 2014-02-07 00:16:39 +01:00
parent 0af197a0f7
commit 45a3b54d32
6 changed files with 115 additions and 94 deletions

View File

@ -353,9 +353,7 @@ class PlayerAPI{
return $this->server->clients; return $this->server->clients;
} }
public function broadcastPacket(array $players, $id, $data = array()){ public function broadcastPacket(array $players, RakNetDataPacket $packet){
$data = new CustomPacketHandler($id, "", $data, true);
$packet = array("raw" => chr($id).$data->raw);
foreach($players as $p){ foreach($players as $p){
$p->dataPacket(false, $packet); $p->dataPacket(false, $packet);
} }

View File

@ -27,7 +27,8 @@ class Player{
private $resendQueue = array(); private $resendQueue = array();
private $ackQueue = array(); private $ackQueue = array();
private $receiveCount = -1; private $receiveCount = -1;
private $buffer = ""; private $buffer;
private $bufferLen = 0;
private $nextBuffer = 0; private $nextBuffer = 0;
private $evid = array(); private $evid = array();
private $lastMovement = 0; private $lastMovement = 0;
@ -114,6 +115,8 @@ class Player{
$this->slot = 0; $this->slot = 0;
$this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1); $this->hotbar = array(0, -1, -1, -1, -1, -1, -1, -1, -1);
$this->packetStats = array(0,0); $this->packetStats = array(0,0);
$this->buffer = new RakNetDataPacket(RakNetInfo::DATA_PACKET_0);
$this->buffer->data = array();
$this->server->schedule(2, array($this, "handlePacketQueues"), array(), true); $this->server->schedule(2, array($this, "handlePacketQueues"), array(), true);
$this->server->schedule(20 * 60, array($this, "clearQueue"), array(), true); $this->server->schedule(20 * 60, array($this, "clearQueue"), array(), true);
$this->evid[] = $this->server->event("server.close", array($this, "close")); $this->evid[] = $this->server->event("server.close", array($this, "close"));
@ -1106,14 +1109,15 @@ class Player{
$safeCount = (int) (($this->MTU - 1) / 4); $safeCount = (int) (($this->MTU - 1) / 4);
$packetCnt = (int) ($ackCnt / $safeCount + 1); $packetCnt = (int) ($ackCnt / $safeCount + 1);
for($p = 0; $p < $packetCnt; ++$p){ for($p = 0; $p < $packetCnt; ++$p){
$acks = array(); $pk = new RakNetPacket(RakNetInfo::ACK);
$pk->packets = array();
for($c = 0; $c < $safeCount; ++$c){ for($c = 0; $c < $safeCount; ++$c){
if(($k = array_pop($this->ackQueue)) === null){ if(($k = array_pop($this->ackQueue)) === null){
break; break;
} }
$acks[] = $k; $pk->packets[] = $k;
} }
$this->send(0xc0, array($acks)); $this->send($pk);
} }
$this->ackQueue = array(); $this->ackQueue = array();
} }
@ -1154,7 +1158,7 @@ class Player{
$limit = $time - 5; //max lag $limit = $time - 5; //max lag
foreach($this->recoveryQueue as $count => $data){ foreach($this->recoveryQueue as $count => $data){
if($data["sendtime"] > $limit){ if($data->sendtime > $limit){
break; break;
} }
unset($this->recoveryQueue[$count]); unset($this->recoveryQueue[$count]);
@ -1165,8 +1169,8 @@ class Player{
foreach($this->resendQueue as $count => $data){ foreach($this->resendQueue as $count => $data){
unset($this->resendQueue[$count]); unset($this->resendQueue[$count]);
$this->packetStats[1]++; $this->packetStats[1]++;
$this->lag[] = microtime(true) - $data["sendtime"]; $this->lag[] = microtime(true) - $data->sendtime;
$cnt = $this->directDataPacket($data["id"], $data, $data["pid"]); $cnt = $this->directDataPacket($data);
if(isset($this->chunkCount[$count])){ if(isset($this->chunkCount[$count])){
unset($this->chunkCount[$count]); unset($this->chunkCount[$count]);
$this->chunkCount[$cnt[0]] = true; $this->chunkCount[$cnt[0]] = true;
@ -2230,17 +2234,20 @@ class Player{
)); ));
} }
public function send($pid, $data = array(), $raw = false){ public function send(RakNetPacket $packet){
if($this->connected === true){ if($this->connected === true){
$this->bandwidthRaw += $this->server->send($pid, $data, $raw, $this->ip, $this->port); $packet->ip = $this->ip;
$packet->port = $this->port;
$this->bandwidthRaw += $this->server->send($packet);
} }
} }
public function sendBuffer(){ public function sendBuffer(){
if(strlen($this->buffer) > 0){ if(strlen($this->buffer) > 0){
$this->directDataPacket(false, array("raw" => $this->buffer), 0x40); $this->directDataPacket($this->buffer);
} }
$this->buffer = ""; $this->buffer = new RakNetDataPacket(RakNetInfo::DATA_PACKET_0);
$this->buffer->data = array();
$this->nextBuffer = microtime(true) + 0.1; $this->nextBuffer = microtime(true) + 0.1;
} }
@ -2272,22 +2279,20 @@ class Player{
return $cnts; return $cnts;
} }
public function directDataPacket($id, $data = array(), $pid = 0x00, $recover = true){ public function directDataPacket(RakNetDataPacket $packet, $reliability = 0, $recover = true){
if($this->connected === false){ if($this->connected === false){
return false; return false;
} }
$data["id"] = $id; $packet->encode();
$data["pid"] = $pid; $pk = new RakNetPacket(RakNetInfo::DATA_PACKET_0);
$data["sendtime"] = microtime(true); $pk->data[] = $packet;
$count = $this->counter[0]++; $pk->seqNumber = $this->counter[0]++;
$pk->sendtime = microtime(true);
if($recover !== false){ if($recover !== false){
$this->recoveryQueue[$count] = $data; $this->recoveryQueue[$pk->seqNumber] = $packet;
} }
$this->send(0x80, array(
$count, $this->send($pk);
$pid,
$data,
));
return array($count); return array($count);
} }
@ -2297,24 +2302,21 @@ class Player{
* *
* @return array|bool * @return array|bool
*/ */
public function dataPacket($id, $data = array()){ public function dataPacket(RakNetDataPacket $packet){
$data["id"] = $id; $packet->encode();
if($id === false){ $len = strlen($packet->buffer) + 1;
$raw = $data["raw"];
}else{
$data = new CustomPacketHandler($id, "", $data, true);
$raw = chr($id).$data->raw;
}
$len = strlen($raw);
$MTU = $this->MTU - 24; $MTU = $this->MTU - 24;
if($len > $MTU){ if($len > $MTU){
return $this->directBigRawPacket(false, $raw); return $this->directBigRawPacket($packet);
} }
if((strlen($this->buffer) + $len) >= $MTU){ if(($this->bufferLen + $len) >= $MTU){
$this->sendBuffer(); $this->sendBuffer();
} }
$this->buffer .= ($this->buffer === "" ? "":"\x40").Utils::writeShort($len << 3).strrev(Utils::writeTriad($this->counter[3]++)).$raw;
$packet->messageIndex = $this->counter[3]++;
$this->buffer->data[] .= $packet;
$this->bufferLen += 6 + $len;
return array(); return array();
} }

View File

@ -421,7 +421,7 @@ class PocketMinecraftServer{
} }
$dump .= "\r\n\r\n"; $dump .= "\r\n\r\n";
$version = new VersionString(); $version = new VersionString();
$dump .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n"; $dump .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".ProtocolInfo::CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n";
$dump .= "Git commit: ".GIT_COMMIT."\r\n"; $dump .= "Git commit: ".GIT_COMMIT."\r\n";
$dump .= "Source SHA1 sum: ".SOURCE_SHA1SUM."\r\n"; $dump .= "Source SHA1 sum: ".SOURCE_SHA1SUM."\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n"; $dump .= "uname -a: ".php_uname("a")."\r\n";
@ -473,29 +473,30 @@ class PocketMinecraftServer{
} }
public static function clientID($ip, $port){ public static function clientID($ip, $port){
//faster than string indexes in PHP //return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM); return md5($ip . ":" . $port . BOOTUP_RANDOM, true);
} }
public function packetHandler($packet){ public function packetHandler(Packet $packet){
$data =& $packet["data"]; $data =& $packet;
$CID = PocketMinecraftServer::clientID($packet["ip"], $packet["port"]); $CID = PocketMinecraftServer::clientID($packet->ip, $packet->port);
if(isset($this->clients[$CID])){ if(isset($this->clients[$CID])){
$this->clients[$CID]->handlePacket($packet["pid"], $data); $this->clients[$CID]->handlePacket($packet);
}else{ }else{
if($this->handle("server.noauthpacket", $packet) === false){ if($this->handle("server.noauthpacket.".$packet->pid(), $packet) === false){
return; return;
} }
switch($packet["pid"]){ switch($packet->pid()){
case 0x01: case RakNetInfo::UNCONNECTED_PING:
case 0x02: case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
if($this->invisible === true){ if($this->invisible === true){
$this->send(0x1c, array( $pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$data[0], $pk->pingID = $packet->pingID;
$this->serverID, $pk->serverID = $this->serverID;
RAKNET_MAGIC, $pk->serverType = $this->serverType;
$this->serverType, $pk->ip = $packet->ip;
), false, $packet["ip"], $packet["port"]); $pk->port = $packet->port;
$this->send($pk);
break; break;
} }
if(!isset($this->custom["times_".$CID])){ if(!isset($this->custom["times_".$CID])){
@ -507,12 +508,13 @@ class PocketMinecraftServer{
} }
$txt = substr($this->description, $this->custom["times_".$CID], $ln); $txt = substr($this->description, $this->custom["times_".$CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt)); $txt .= substr($this->description, 0, $ln - strlen($txt));
$this->send(0x1c, array( $pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$data[0], $pk->pingID = $packet->pingID;
$this->serverID, $pk->serverID = $this->serverID;
RAKNET_MAGIC, $pk->serverType = $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt;
$this->serverType. $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt, $pk->ip = $packet->ip;
), false, $packet["ip"], $packet["port"]); $pk->port = $packet->port;
$this->send($pk);
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description); $this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
break; break;
case 0x05: case 0x05:
@ -556,8 +558,8 @@ class PocketMinecraftServer{
} }
} }
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){ public function send(Packet $packet){
return $this->interface->writePacket($pid, $data, $raw, $dest, $port); return $this->interface->writePacket($packet);
} }
public function process(){ public function process(){

View File

@ -21,7 +21,7 @@
abstract class RakNetDataPacket extends stdClass{ abstract class RakNetDataPacket extends stdClass{
private $offset = 0; private $offset = 0;
private $buffer = b""; public $buffer = b"";
public $reliability = 0; public $reliability = 0;
public $hasSplit = false; public $hasSplit = false;

View File

@ -57,35 +57,35 @@ class RakNetInfo{
public static function isRakNet($pid){ public static function isValid($pid){
switch((int) $pid){ switch((int) $pid){
case UNCONNECTED_PING: case RakNetInfo::UNCONNECTED_PING:
case UNCONNECTED_PING_OPEN_CONNECTIONS: case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
case OPEN_CONNECTION_REQUEST_1: case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
case OPEN_CONNECTION_REPLY_1: case RakNetInfo::OPEN_CONNECTION_REPLY_1:
case OPEN_CONNECTION_REQUEST_2: case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
case OPEN_CONNECTION_REPLY_2: case RakNetInfo::OPEN_CONNECTION_REPLY_2:
case INCOMPATIBLE_PROTOCOL_VERSION: case RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION:
case UNCONNECTED_PONG: case RakNetInfo::UNCONNECTED_PONG:
case ADVERTISE_SYSTEM: case RakNetInfo::ADVERTISE_SYSTEM:
case DATA_PACKET_0: case RakNetInfo::DATA_PACKET_0:
case DATA_PACKET_1: case RakNetInfo::DATA_PACKET_1:
case DATA_PACKET_2: case RakNetInfo::DATA_PACKET_2:
case DATA_PACKET_3: case RakNetInfo::DATA_PACKET_3:
case DATA_PACKET_4: case RakNetInfo::DATA_PACKET_4:
case DATA_PACKET_5: case RakNetInfo::DATA_PACKET_5:
case DATA_PACKET_6: case RakNetInfo::DATA_PACKET_6:
case DATA_PACKET_7: case RakNetInfo::DATA_PACKET_7:
case DATA_PACKET_8: case RakNetInfo::DATA_PACKET_8:
case DATA_PACKET_9: case RakNetInfo::DATA_PACKET_9:
case DATA_PACKET_A: case RakNetInfo::DATA_PACKET_A:
case DATA_PACKET_B: case RakNetInfo::DATA_PACKET_B:
case DATA_PACKET_C: case RakNetInfo::DATA_PACKET_C:
case DATA_PACKET_D: case RakNetInfo::DATA_PACKET_D:
case DATA_PACKET_E: case RakNetInfo::DATA_PACKET_E:
case DATA_PACKET_F: case RakNetInfo::DATA_PACKET_F:
case NACK: case RakNetInfo::NACK:
case ACK: case RakNetInfo::ACK:
return true; return true;
default: default:
return false; return false;

View File

@ -37,7 +37,7 @@ class RakNetParser{
} }
public function pid(){ public function pid(){
return (int) $this->pid; return (int) $this->id;
} }
private function get($len){ private function get($len){
@ -120,6 +120,25 @@ class RakNetParser{
$this->data[] = $this->parseDataPacket(); $this->data[] = $this->parseDataPacket();
} }
break; break;
case RakNetInfo::NACK:
case RakNetInfo::ACK:
$count = $this->getShort();
$this->packets = array();
for($i = 0; $i < $count and !$this->feof(); ++$i){
if($this->getByte() === 0){
$start = $this->getLTriad();
$end = $this->getLTriad();
if(($end - $start) > 4096){
$end = $start + 4096;
}
for($c = $start; $c <= $end; ++$c){
$this->packets[] = $c;
}
}else{
$this->packets[] = $this->getLTriad();
}
}
break;
default: default:
$this->packet = false; $this->packet = false;
break; break;