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;
}
/**
* @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.
*
@ -1253,13 +1272,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
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($client){ //gamemode change by client in the GUI
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
$this->sendGamemode();
}
return false;
}
@ -1286,9 +1302,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
if(!$client){ //Gamemode changed by server, do not send for client changes
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendGamemode();
}else{
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;
}
/**
* @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
*/
@ -1816,12 +1840,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk = new StartGamePacket();
$pk->entityUniqueId = $this->id;
$pk->entityRuntimeId = $this->id;
$pk->playerGamemode = Player::getClientFriendlyGamemode($this->gamemode);
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->seed = -1;
$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->spawnX = $spawnPosition->getFloorX();
$pk->spawnY = $spawnPosition->getFloorY();
@ -3165,11 +3190,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
}
public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{
if($packet->gamemode !== ($this->gamemode & 0x01)){
//GUI gamemode change, set it back to original for now (only possible through client bug or hack with current allowed client permissions)
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
if($packet->gamemode !== $this->gamemode){
//Set this back to default. TODO: handle this properly
$this->sendGamemode();
$this->sendSettings();
}
return true;