Fixed spawning problems because of packets

This commit is contained in:
Shoghi Cervantes 2014-02-07 18:03:11 +01:00
parent 84638098d0
commit ac3472eff4
7 changed files with 55 additions and 44 deletions

View File

@ -355,7 +355,7 @@ class PlayerAPI{
public function broadcastPacket(array $players, RakNetDataPacket $packet){ public function broadcastPacket(array $players, RakNetDataPacket $packet){
foreach($players as $p){ foreach($players as $p){
$p->dataPacket(false, $packet); $p->dataPacket($packet);
} }
} }

View File

@ -115,7 +115,7 @@ 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 = new RakNetPacket(RakNetInfo::DATA_PACKET_0);
$this->buffer->data = array(); $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);
@ -302,7 +302,6 @@ class Player{
$this->receiveQueue = array(); $this->receiveQueue = array();
$this->resendQueue = array(); $this->resendQueue = array();
$this->ackQueue = array(); $this->ackQueue = array();
$this->server->interface->stopChunked($this->CID);
$this->server->api->player->remove($this->CID); $this->server->api->player->remove($this->CID);
if($msg === true and $this->username != ""){ if($msg === true and $this->username != ""){
$this->server->api->chat->broadcast($this->username." left the game"); $this->server->api->chat->broadcast($this->username." left the game");
@ -1162,6 +1161,7 @@ class Player{
} }
$this->received[$p->messageIndex] = true; $this->received[$p->messageIndex] = true;
} }
$p->decode();
$this->handleDataPacket($p); $this->handleDataPacket($p);
} }
} }
@ -1185,8 +1185,8 @@ class Player{
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;
$data->decode(); $data->sendtime = microtime(true);
$cnt = $this->directDataPacket($data); $cnt = $this->send($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;
@ -1195,15 +1195,15 @@ class Player{
} }
} }
public function handlePacket($packet){ public function handlePacket(RakNetPacket $packet){
if($this->connected === true){ if($this->connected === true){
$this->timeout = microtime(true) + 20; $this->timeout = microtime(true) + 20;
switch($pid){ switch($packet->pid()){
case RakNetInfo::NACK: case RakNetInfo::NACK:
foreach($packet->packets as $count){ foreach($packet->packets as $count){
if(isset($this->recoveryQueue[$count])){ if(isset($this->recoveryQueue[$count])){
$this->resendQueue[$count] =& $this->recoveryQueue[$count]; $this->resendQueue[$count] =& $this->recoveryQueue[$count];
$this->lag[] = microtime(true) - $this->recoveryQueue[$count]["sendtime"]; $this->lag[] = microtime(true) - $this->recoveryQueue[$count]->sendtime;
unset($this->recoveryQueue[$count]); unset($this->recoveryQueue[$count]);
} }
++$this->packetStats[1]; ++$this->packetStats[1];
@ -1213,7 +1213,7 @@ class Player{
case RakNetInfo::ACK: case RakNetInfo::ACK:
foreach($packet->packets as $count){ foreach($packet->packets as $count){
if(isset($this->recoveryQueue[$count])){ if(isset($this->recoveryQueue[$count])){
$this->lag[] = microtime(true) - $this->recoveryQueue[$count]["sendtime"]; $this->lag[] = microtime(true) - $this->recoveryQueue[$count]->sendtime;
unset($this->recoveryQueue[$count]); unset($this->recoveryQueue[$count]);
unset($this->resendQueue[$count]); unset($this->resendQueue[$count]);
} }
@ -1239,8 +1239,8 @@ class Player{
case RakNetInfo::DATA_PACKET_F: case RakNetInfo::DATA_PACKET_F:
$this->ackQueue[] = $packet->seqNumber; $this->ackQueue[] = $packet->seqNumber;
$this->receiveQueue[$packet->seqNumber] = array(); $this->receiveQueue[$packet->seqNumber] = array();
foreach($packet->data as $packet){ foreach($packet->data as $pk){
$this->receiveQueue[$packet->seqNumber][] = $packet; $this->receiveQueue[$packet->seqNumber][] = $pk;
} }
break; break;
} }
@ -1268,7 +1268,7 @@ class Player{
} }
$pk = new ServerHandshakePacket; $pk = new ServerHandshakePacket;
$pk->port = $this->port; $pk->port = $this->port;
$pk->session = $data["session"]; $pk->session = $packet->session;
$pk->session2 = Utils::readLong("\x00\x00\x00\x00\x04\x44\x0b\xa9"); $pk->session2 = Utils::readLong("\x00\x00\x00\x00\x04\x44\x0b\xa9");
$this->dataPacket($pk); $this->dataPacket($pk);
break; break;
@ -2069,19 +2069,19 @@ class Player{
if($packet->windowid === 0){ if($packet->windowid === 0){
$craft = false; $craft = false;
$slot = $this->getSlot($packet->slot); $slot = $this->getSlot($packet->slot);
if($slot->count >= $packet->item->count and (($slot->getID() === $packet->item->getID() and $slot->getMetadata() === $packet->item->getMetadata()) or ($packet->item->getID() === AIR and $packet->item->count() === 0)) and !isset($this->craftingItems[$packet->slot])){ //Crafting recipe if($slot->count >= $packet->item->count and (($slot->getID() === $packet->item->getID() and $slot->getMetadata() === $packet->item->getMetadata()) or ($packet->item->getID() === AIR and $packet->item->count === 0)) and !isset($this->craftingItems[$packet->slot])){ //Crafting recipe
$use = BlockAPI::getItem($slot->getID(), $slot->getMetadata(), $slot->count - $packet->item->count()); $use = BlockAPI::getItem($slot->getID(), $slot->getMetadata(), $slot->count - $packet->item->count);
$this->craftingItems[$packet->slot] = $use; $this->craftingItems[$packet->slot] = $use;
$craft = true; $craft = true;
}elseif($slot->count <= $packet->item->count() and ($slot->getID() === AIR or ($slot->getID() === $packet->item->getID() and $slot->getMetadata() === $packet->item->getMetadata()))){ //Crafting final }elseif($slot->count <= $packet->item->count and ($slot->getID() === AIR or ($slot->getID() === $packet->item->getID() and $slot->getMetadata() === $packet->item->getMetadata()))){ //Crafting final
$craftItem = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count() - $slot->count); $craftItem = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count - $slot->count);
if(count($this->toCraft) === 0){ if(count($this->toCraft) === 0){
$this->toCraft[-1] = 0; $this->toCraft[-1] = 0;
} }
$this->toCraft[$packet->slot] = $craftItem; $this->toCraft[$packet->slot] = $craftItem;
$craft = true; $craft = true;
}elseif(((count($this->toCraft) === 1 and isset($this->toCraft[-1])) or count($this->toCraft) === 0) and $slot->count > 0 and $slot->getID() > AIR and ($slot->getID() !== $packet->item->getID() or $slot->getMetadata() !== $packet->item->getMetadata())){ //Crafting final }elseif(((count($this->toCraft) === 1 and isset($this->toCraft[-1])) or count($this->toCraft) === 0) and $slot->count > 0 and $slot->getID() > AIR and ($slot->getID() !== $packet->item->getID() or $slot->getMetadata() !== $packet->item->getMetadata())){ //Crafting final
$craftItem = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count()); $craftItem = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count);
if(count($this->toCraft) === 0){ if(count($this->toCraft) === 0){
$this->toCraft[-1] = 0; $this->toCraft[-1] = 0;
} }
@ -2126,7 +2126,7 @@ class Player{
break; break;
} }
$item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count()); $item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count);
$slot = $tile->getSlot($slotn); $slot = $tile->getSlot($slotn);
if($this->server->api->dhandle("player.container.slot", array( if($this->server->api->dhandle("player.container.slot", array(
@ -2164,7 +2164,7 @@ class Player{
if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $packet->slot < 0 or ($tile->class === TILE_CHEST and $packet->slot >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $packet->slot >= FURNACE_SLOTS)){ if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $packet->slot < 0 or ($tile->class === TILE_CHEST and $packet->slot >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $packet->slot >= FURNACE_SLOTS)){
break; break;
} }
$item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count()); $item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count);
$slot = $tile->getSlot($packet->slot); $slot = $tile->getSlot($packet->slot);
if($this->server->api->dhandle("player.container.slot", array( if($this->server->api->dhandle("player.container.slot", array(
@ -2235,7 +2235,7 @@ class Player{
} }
break; break;
default: default:
console("[DEBUG] Unhandled 0x".dechex($pid)." data packet for ".$this->username." (".$this->clientID."): ".print_r($data, true), true, true, 2); console("[DEBUG] Unhandled 0x".dechex($packet->pid())." data packet for ".$this->username." (".$this->clientID."): ".print_r($data, true), true, true, 2);
break; break;
} }
} }
@ -2261,7 +2261,7 @@ class Player{
if($player === $this){ if($player === $this){
$pk = new ContainerSetContentPacket; $pk = new ContainerSetContentPacket;
$pk->windowid = 0x78; //Armor window id $pk->windowid = 0x78; //Armor window id
$pk->slots = $data["slots"]; $pk->slots = $this->armor;
$this->dataPacket($pk); $this->dataPacket($pk);
}else{ }else{
$pk = new PlayerArmorEquipmentPacket; $pk = new PlayerArmorEquipmentPacket;
@ -2299,10 +2299,12 @@ class Player{
} }
public function sendBuffer(){ public function sendBuffer(){
if(strlen($this->buffer) > 0){ if($this->bufferLen > 0 and $this->buffer instanceof RakNetPacket){
$this->directDataPacket($this->buffer); $this->buffer->seqNumber = $this->counter[0]++;
$this->send($this->buffer);
} }
$this->buffer = new RakNetDataPacket(RakNetInfo::DATA_PACKET_0); $this->bufferLen = 0;
$this->buffer = new RakNetPacket(RakNetInfo::DATA_PACKET_0);
$this->buffer->data = array(); $this->buffer->data = array();
$this->nextBuffer = microtime(true) + 0.1; $this->nextBuffer = microtime(true) + 0.1;
} }
@ -2315,7 +2317,7 @@ class Player{
$sendtime = microtime(true); $sendtime = microtime(true);
$size = $this->MTU - 34; $size = $this->MTU - 34;
$buffer = str_split(chr($packet->pid). $packet->buffer, $size); $buffer = str_split(chr($packet->pid()). $packet->buffer, $size);
$bigCnt = $this->bigCnt; $bigCnt = $this->bigCnt;
$this->bigCnt = ($this->bigCnt + 1) % 0x10000; $this->bigCnt = ($this->bigCnt + 1) % 0x10000;
$cnts = array(); $cnts = array();
@ -2353,11 +2355,11 @@ class Player{
$pk->seqNumber = $this->counter[0]++; $pk->seqNumber = $this->counter[0]++;
$pk->sendtime = microtime(true); $pk->sendtime = microtime(true);
if($recover !== false){ if($recover !== false){
$this->recoveryQueue[$pk->seqNumber] = $packet; $this->recoveryQueue[$pk->seqNumber] = $pk;
} }
$this->send($pk); $this->send($pk);
return array($count); return array($pk->seqNumber);
} }
/** /**

View File

@ -473,8 +473,8 @@ class PocketMinecraftServer{
} }
public static function clientID($ip, $port){ public static function clientID($ip, $port){
//return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM); return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
return $ip . ":" . $port; //return $ip . ":" . $port;
} }
public function packetHandler(Packet $packet){ public function packetHandler(Packet $packet){
@ -518,8 +518,8 @@ class PocketMinecraftServer{
$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 RakNetInfo::OPEN_CONNECTION_REQUEST_1: case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
if($packet->structure !== RAKNET_STRUCTURE){ if($packet->structure !== RakNetInfo::STRUCTURE){
console("[DEBUG] Incorrect structure #$version from ".$packet->ip.":".$packet->port, true, true, 2); console("[DEBUG] Incorrect structure #".$packet->structure." from ".$packet->ip.":".$packet->port, true, true, 2);
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION); $pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
$pk->serverID = $this->serverID; $pk->serverID = $this->serverID;
$pk->ip = $packet->ip; $pk->ip = $packet->ip;

View File

@ -46,7 +46,7 @@ class ContainerSetContentPacket extends RakNetDataPacket{
$this->putByte($this->windowid); $this->putByte($this->windowid);
$this->putShort(count($this->slots)); $this->putShort(count($this->slots));
foreach($this->slots as $slot){ foreach($this->slots as $slot){
$this->putSlot($item); $this->putSlot($slot);
} }
if($this->windowid === 0 and count($this->hotbar) > 0){ if($this->windowid === 0 and count($this->hotbar) > 0){
$this->putShort(count($this->hotbar)); $this->putShort(count($this->hotbar));

View File

@ -75,8 +75,8 @@ class RakNetCodec{
case RakNetInfo::DATA_PACKET_D: case RakNetInfo::DATA_PACKET_D:
case RakNetInfo::DATA_PACKET_E: case RakNetInfo::DATA_PACKET_E:
case RakNetInfo::DATA_PACKET_F: case RakNetInfo::DATA_PACKET_F:
$this->putLTriad($this->seqNumber); $this->putLTriad($this->packet->seqNumber);
foreach($this->data as $pk){ foreach($this->packet->data as $pk){
$this->encodeDataPacket($pk); $this->encodeDataPacket($pk);
} }
break; break;
@ -170,11 +170,11 @@ class RakNetCodec{
} }
protected function putTriad($v){ protected function putTriad($v){
$this->buffer .= Utils::putTriad($v); $this->buffer .= Utils::writeTriad($v);
} }
protected function putLTriad($v){ protected function putLTriad($v){
$this->buffer .= strrev(Utils::putTriad($v)); $this->buffer .= strrev(Utils::writeTriad($v));
} }
protected function putByte($v){ protected function putByte($v){

View File

@ -90,21 +90,30 @@ abstract class RakNetDataPacket extends stdClass{
protected function putShort($v){ protected function putShort($v){
$this->buffer .= Utils::writeShort($v); $this->buffer .= Utils::writeShort($v);
} }
protected function getFloat(){
return Utils::readFloat($this->get(4));
}
protected function putFloat($v){
$this->buffer .= Utils::writeFloat($v);
}
protected function getTriad(){ protected function getTriad(){
return Utils::readTriad($this->get(3)); return Utils::readTriad($this->get(3));
} }
protected function putTriad($v){ protected function putTriad($v){
$this->buffer .= Utils::putTriad($v); $this->buffer .= Utils::writeTriad($v);
} }
protected function getLTriad(){ protected function getLTriad(){
return Utils::readTriad(strrev($this->get(3))); return Utils::readTriad(strrev($this->get(3)));
} }
protected function putLTriad($v){ protected function putLTriad($v){
$this->buffer .= strrev(Utils::putTriad($v)); $this->buffer .= strrev(Utils::writeTriad($v));
} }
protected function getByte(){ protected function getByte(){

View File

@ -108,16 +108,16 @@ class RakNetParser{
case RakNetInfo::DATA_PACKET_D: case RakNetInfo::DATA_PACKET_D:
case RakNetInfo::DATA_PACKET_E: case RakNetInfo::DATA_PACKET_E:
case RakNetInfo::DATA_PACKET_F: case RakNetInfo::DATA_PACKET_F:
$this->seqNumber = $this->getLTriad(); $this->packet->seqNumber = $this->getLTriad();
$this->data = array(); $this->packet->data = array();
while(!$this->feof()){ while(!$this->feof()){
$this->data[] = $this->parseDataPacket(); $this->packet->data[] = $this->parseDataPacket();
} }
break; break;
case RakNetInfo::NACK: case RakNetInfo::NACK:
case RakNetInfo::ACK: case RakNetInfo::ACK:
$count = $this->getShort(); $count = $this->getShort();
$this->packets = array(); $this->packet->packets = array();
for($i = 0; $i < $count and !$this->feof(); ++$i){ for($i = 0; $i < $count and !$this->feof(); ++$i){
if($this->getByte() === 0){ if($this->getByte() === 0){
$start = $this->getLTriad(); $start = $this->getLTriad();
@ -126,10 +126,10 @@ class RakNetParser{
$end = $start + 4096; $end = $start + 4096;
} }
for($c = $start; $c <= $end; ++$c){ for($c = $start; $c <= $end; ++$c){
$this->packets[] = $c; $this->packet->packets[] = $c;
} }
}else{ }else{
$this->packets[] = $this->getLTriad(); $this->packet->packets[] = $this->getLTriad();
} }
} }
break; break;