Protocol changes for 1.1.0.3, fixed red sky, fixed crashes

This commit is contained in:
Dylan K. Taylor 2017-04-14 15:17:56 +01:00
parent f3ab45e7d5
commit a327a74ece
3 changed files with 47 additions and 17 deletions

View File

@ -1240,6 +1240,25 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return $this->gamemode; return $this->gamemode;
} }
/**
* @internal
*
* Returns a client-friendly gamemode of the specified real gamemode
* This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure)
*
* TODO: remove this when Spectator Mode gets added properly to MCPE
*
* @param int $gamemode
*/
public static function getClientFriendlyGamemode(int $gamemode) : int{
$gamemode &= 0x03;
if($gamemode === Player::SPECTATOR){
return Player::CREATIVE;
}
return $gamemode;
}
/** /**
* Sets the gamemode, and if needed, kicks the Player. * Sets the gamemode, and if needed, kicks the Player.
* *
@ -1253,13 +1272,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm)); $this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, $gm));
if($ev->isCancelled()){ if($ev->isCancelled()){
if($client){ //gamemode change by client in the GUI if($client){ //gamemode change by client in the GUI
$pk = new SetPlayerGameTypePacket(); $this->sendGamemode();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
} }
return false; return false;
} }
@ -1286,9 +1302,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode); $this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
if(!$client){ //Gamemode changed by server, do not send for client changes if(!$client){ //Gamemode changed by server, do not send for client changes
$pk = new SetPlayerGameTypePacket(); $this->sendGamemode();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
}else{ }else{
Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)])); Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)]));
} }
@ -1305,6 +1319,16 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
return true; return true;
} }
/**
* @internal
* Sends the player's gamemode to the client.
*/
public function sendGamemode(){
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = Player::getClientFriendlyGamemode($this->gamemode);
$this->dataPacket($pk);
}
/** /**
* Sends all the option flags * Sends all the option flags
*/ */
@ -1816,12 +1840,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk = new StartGamePacket(); $pk = new StartGamePacket();
$pk->entityUniqueId = $this->id; $pk->entityUniqueId = $this->id;
$pk->entityRuntimeId = $this->id; $pk->entityRuntimeId = $this->id;
$pk->playerGamemode = Player::getClientFriendlyGamemode($this->gamemode);
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;
$pk->seed = -1; $pk->seed = -1;
$pk->dimension = 0; //TODO: implement this properly $pk->dimension = 0; //TODO: implement this properly
$pk->gamemode = $this->gamemode & 0x01; $pk->worldGamemode = Player::getClientFriendlyGamemode($this->server->getGamemode());
$pk->difficulty = $this->server->getDifficulty(); $pk->difficulty = $this->server->getDifficulty();
$pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnX = $spawnPosition->getFloorX();
$pk->spawnY = $spawnPosition->getFloorY(); $pk->spawnY = $spawnPosition->getFloorY();
@ -3165,11 +3190,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
} }
public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{
if($packet->gamemode !== ($this->gamemode & 0x01)){ if($packet->gamemode !== $this->gamemode){
//GUI gamemode change, set it back to original for now (only possible through client bug or hack with current allowed client permissions) //Set this back to default. TODO: handle this properly
$pk = new SetPlayerGameTypePacket(); $this->sendGamemode();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings(); $this->sendSettings();
} }
return true; return true;

View File

@ -42,6 +42,7 @@ class MovePlayerPacket extends DataPacket{
public $pitch; public $pitch;
public $mode = self::MODE_NORMAL; public $mode = self::MODE_NORMAL;
public $onGround; public $onGround;
public $eid2; //???
public function decode(){ public function decode(){
$this->eid = $this->getEntityRuntimeId(); $this->eid = $this->getEntityRuntimeId();
@ -51,6 +52,7 @@ class MovePlayerPacket extends DataPacket{
$this->bodyYaw = $this->getLFloat(); $this->bodyYaw = $this->getLFloat();
$this->mode = $this->getByte(); $this->mode = $this->getByte();
$this->onGround = $this->getBool(); $this->onGround = $this->getBool();
$this->eid2 = $this->getEntityRuntimeId();
} }
public function encode(){ public function encode(){
@ -62,6 +64,7 @@ class MovePlayerPacket extends DataPacket{
$this->putLFloat($this->bodyYaw); //TODO $this->putLFloat($this->bodyYaw); //TODO
$this->putByte($this->mode); $this->putByte($this->mode);
$this->putBool($this->onGround); $this->putBool($this->onGround);
$this->putEntityRuntimeId($this->eid2);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

View File

@ -31,13 +31,14 @@ class StartGamePacket extends DataPacket{
public $entityUniqueId; public $entityUniqueId;
public $entityRuntimeId; public $entityRuntimeId;
public $playerGamemode;
public $x; public $x;
public $y; public $y;
public $z; public $z;
public $seed; public $seed;
public $dimension; public $dimension;
public $generator = 1; //default infinite - 0 old, 1 infinite, 2 flat public $generator = 1; //default infinite - 0 old, 1 infinite, 2 flat
public $gamemode; public $worldGamemode;
public $difficulty; public $difficulty;
public $spawnX; public $spawnX;
public $spawnY; public $spawnY;
@ -51,6 +52,7 @@ class StartGamePacket extends DataPacket{
public $isTexturePacksRequired = 0; public $isTexturePacksRequired = 0;
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
public $worldName; public $worldName;
public $premiumWorldTemplateId = "";
public function decode(){ public function decode(){
@ -60,13 +62,14 @@ class StartGamePacket extends DataPacket{
$this->reset(); $this->reset();
$this->putEntityUniqueId($this->entityUniqueId); $this->putEntityUniqueId($this->entityUniqueId);
$this->putEntityRuntimeId($this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId);
$this->putVarInt($this->playerGamemode); //client gamemode, other field is world gamemode
$this->putVector3f($this->x, $this->y, $this->z); $this->putVector3f($this->x, $this->y, $this->z);
$this->putLFloat(0); //TODO: find out what these are (yaw/pitch?) $this->putLFloat(0); //TODO: yaw/pitch
$this->putLFloat(0); $this->putLFloat(0);
$this->putVarInt($this->seed); $this->putVarInt($this->seed);
$this->putVarInt($this->dimension); $this->putVarInt($this->dimension);
$this->putVarInt($this->generator); $this->putVarInt($this->generator);
$this->putVarInt($this->gamemode); $this->putVarInt($this->worldGamemode);
$this->putVarInt($this->difficulty); $this->putVarInt($this->difficulty);
$this->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); $this->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ);
$this->putBool($this->hasAchievementsDisabled); $this->putBool($this->hasAchievementsDisabled);
@ -79,6 +82,7 @@ class StartGamePacket extends DataPacket{
$this->putUnsignedVarInt(0); //TODO: gamerules $this->putUnsignedVarInt(0); //TODO: gamerules
$this->putString($this->levelId); $this->putString($this->levelId);
$this->putString($this->worldName); $this->putString($this->worldName);
$this->putString($this->premiumWorldTemplateId);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{