Inventory: Fix creative/spectator inventory sending

This commit is contained in:
Dylan K. Taylor 2016-09-06 13:05:53 +01:00
parent 5851e7fe55
commit f14a8e46be
3 changed files with 37 additions and 45 deletions

View File

@ -1096,19 +1096,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->dataPacket($pk); $this->dataPacket($pk);
$this->sendSettings(); $this->sendSettings();
if($this->gamemode === Player::SPECTATOR){
$pk = new ContainerSetContentPacket();
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
$this->dataPacket($pk);
}else{
$pk = new ContainerSetContentPacket();
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
foreach(Item::getCreativeItems() as $item){
$pk->slots[] = clone $item;
}
$this->dataPacket($pk);
}
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
$this->inventory->sendContents($this->getViewers()); $this->inventory->sendContents($this->getViewers());
$this->inventory->sendHeldItem($this->hasSpawned); $this->inventory->sendHeldItem($this->hasSpawned);
@ -1183,22 +1170,31 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->dataPacket($pk); $this->dataPacket($pk);
} }
public function isSurvival(){ /**
* WARNING: This method does NOT return literal gamemode is survival, it will also return true for adventure mode players.
*/
public function isSurvival() : bool{
return ($this->gamemode & 0x01) === 0; return ($this->gamemode & 0x01) === 0;
} }
public function isCreative(){ /**
return ($this->gamemode & 0x01) > 0; * WARNING: This method does NOT return literal gamemode is creative, it will also return true for creative mode players.
*/
public function isCreative() : bool{
return ($this->gamemode & 0x01) === 1;
} }
public function isSpectator(){ /**
return $this->gamemode === 3; * WARNING: This method does NOT return literal gamemode is adventure, it will also return true for spectator mode players.
} */
public function isAdventure() : bool{
public function isAdventure(){
return ($this->gamemode & 0x02) > 0; return ($this->gamemode & 0x02) > 0;
} }
public function isSpectator() : bool{
return $this->gamemode === 3;
}
public function getDrops(){ public function getDrops(){
if(!$this->isCreative()){ if(!$this->isCreative()){
return parent::getDrops(); return parent::getDrops();
@ -1632,7 +1628,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$nbt->playerGameType = new IntTag("playerGameType", $this->gamemode); $nbt->playerGameType = new IntTag("playerGameType", $this->gamemode);
} }
$this->allowFlight = $this->isCreative(); $this->allowFlight = (bool) $this->gamemode & 0x01;
if(($level = $this->server->getLevelByName($nbt["Level"])) === null){ if(($level = $this->server->getLevelByName($nbt["Level"])) === null){
$this->setLevel($this->server->getDefaultLevel()); $this->setLevel($this->server->getDefaultLevel());
@ -1737,17 +1733,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->setRemoveFormat(false); $this->setRemoveFormat(false);
} }
if($this->gamemode === Player::SPECTATOR){
$pk = new ContainerSetContentPacket();
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
$this->dataPacket($pk);
}else{
$pk = new ContainerSetContentPacket();
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
$pk->slots = Item::getCreativeItems();
$this->dataPacket($pk);
}
$this->forceMovement = $this->teleportPosition = $this->getPosition(); $this->forceMovement = $this->teleportPosition = $this->getPosition();
$this->server->onPlayerLogin($this); $this->server->onPlayerLogin($this);

View File

@ -58,7 +58,7 @@ class InventoryType{
static::$default[static::CHEST] = new InventoryType(27, "Chest", 0); static::$default[static::CHEST] = new InventoryType(27, "Chest", 0);
static::$default[static::DOUBLE_CHEST] = new InventoryType(27 + 27, "DoubleTag Chest", 0); static::$default[static::DOUBLE_CHEST] = new InventoryType(27 + 27, "DoubleTag Chest", 0);
static::$default[static::PLAYER] = new InventoryType(49, "Player", 0); //36 CONTAINER, 4 ARMOR (9 reference HOTBAR slots) static::$default[static::PLAYER] = new InventoryType(36 + 4, "Player", 0); //36 CONTAINER, 4 ARMOR
static::$default[static::FURNACE] = new InventoryType(3, "Furnace", 2); static::$default[static::FURNACE] = new InventoryType(3, "Furnace", 2);
static::$default[static::CRAFTING] = new InventoryType(5, "Crafting", 1); //4 CRAFTING slots, 1 RESULT static::$default[static::CRAFTING] = new InventoryType(5, "Crafting", 1); //4 CRAFTING slots, 1 RESULT
static::$default[static::WORKBENCH] = new InventoryType(10, "Crafting", 1); //9 CRAFTING slots, 1 RESULT static::$default[static::WORKBENCH] = new InventoryType(10, "Crafting", 1); //9 CRAFTING slots, 1 RESULT

View File

@ -384,16 +384,14 @@ class PlayerInventory extends BaseInventory{
$pk = new ContainerSetContentPacket(); $pk = new ContainerSetContentPacket();
$pk->slots = []; $pk->slots = [];
$holder = $this->getHolder();
if($holder instanceof Player and $holder->isCreative()){ for($i = 0; $i < $this->getSize(); ++$i){ //Do not send armor by error here
//TODO: Remove this workaround because of broken client $pk->slots[$i] = $this->getItem($i);
foreach(Item::getCreativeItems() as $i => $item){ }
$pk->slots[$i] = Item::getCreativeItem($i);
} //Because PE is stupid and shows 9 less slots than you send it, give it 9 dummy slots so it shows all the REAL slots.
}else{ for($i = $this->getSize(); $i < $this->getSize() + $this->getHotbarSize(); ++$i){
for($i = 0; $i < $this->getSize(); ++$i){ //Do not send armor by error here $pk->slots[$i] = Item::get(Item::AIR, 0, 0);
$pk->slots[$i] = $this->getItem($i);
}
} }
foreach($target as $player){ foreach($target as $player){
@ -401,7 +399,16 @@ class PlayerInventory extends BaseInventory{
if($player === $this->getHolder()){ if($player === $this->getHolder()){
for($i = 0; $i < $this->getHotbarSize(); ++$i){ for($i = 0; $i < $this->getHotbarSize(); ++$i){
$index = $this->getHotbarSlotIndex($i); $index = $this->getHotbarSlotIndex($i);
$pk->hotbar[] = $index <= -1 ? -1 : $index + 9; $pk->hotbar[] = $index <= -1 ? -1 : $index + $this->getHotbarSize();
}
if($player->getGamemode() & 0x01 === 0x01){ //Send special inventory for creative or spectator
$pk2 = new ContainerSetContentPacket();
$pk2->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
if($player->getGamemode() === Player::CREATIVE){
$pk2->slots = Item::getCreativeItems();
}
$player->dataPacket($pk2);
} }
} }
if(($id = $player->getWindowId($this)) === -1 or $player->spawned !== true){ if(($id = $player->getWindowId($this)) === -1 or $player->spawned !== true){