mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-10-18 20:14:31 +00:00
Updated BedrockProtocol to pmmp/BedrockProtocol@97fa88e9ef
This commit is contained in:
@@ -45,6 +45,7 @@ use pocketmine\network\mcpe\protocol\CreativeContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\InventoryContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\BlockPosition;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
|
||||
@@ -164,26 +165,27 @@ class InventoryManager{
|
||||
//TODO: we should be using some kind of tagging system to identify the types. Instanceof is flaky especially
|
||||
//if the class isn't final, not to mention being inflexible.
|
||||
if($inv instanceof BlockInventory){
|
||||
$blockPosition = BlockPosition::fromVector3($inv->getHolder());
|
||||
switch(true){
|
||||
case $inv instanceof LoomInventory:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::LOOM, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::LOOM, $blockPosition)];
|
||||
case $inv instanceof FurnaceInventory:
|
||||
return match($inv->getFurnaceType()->id()){
|
||||
FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())],
|
||||
FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BLAST_FURNACE, $inv->getHolder())],
|
||||
FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::SMOKER, $inv->getHolder())],
|
||||
FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::FURNACE, $blockPosition)],
|
||||
FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::BLAST_FURNACE, $blockPosition)],
|
||||
FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::SMOKER, $blockPosition)],
|
||||
default => throw new AssumptionFailedError("Unreachable")
|
||||
};
|
||||
case $inv instanceof EnchantInventory:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::ENCHANTMENT, $blockPosition)];
|
||||
case $inv instanceof BrewingStandInventory:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BREWING_STAND, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::BREWING_STAND, $blockPosition)];
|
||||
case $inv instanceof AnvilInventory:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ANVIL, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::ANVIL, $blockPosition)];
|
||||
case $inv instanceof HopperInventory:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::HOPPER, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::HOPPER, $blockPosition)];
|
||||
default:
|
||||
return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::CONTAINER, $inv->getHolder())];
|
||||
return [ContainerOpenPacket::blockInv($id, WindowTypes::CONTAINER, $blockPosition)];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -279,6 +281,7 @@ class InventoryManager{
|
||||
$this->player->getId(),
|
||||
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand())),
|
||||
$selected,
|
||||
$selected,
|
||||
ContainerIds::INVENTORY
|
||||
));
|
||||
$this->clientSelectedHotbarSlot = $selected;
|
||||
|
@@ -88,6 +88,7 @@ use pocketmine\network\mcpe\protocol\SetTitlePacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\TextPacket;
|
||||
use pocketmine\network\mcpe\protocol\TransferPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\BlockPosition;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandData;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
|
||||
@@ -727,7 +728,7 @@ class NetworkSession{
|
||||
$pitch = $pitch ?? $location->getPitch();
|
||||
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->entityRuntimeId = $this->player->getId();
|
||||
$pk->actorRuntimeId = $this->player->getId();
|
||||
$pk->position = $this->player->getOffsetPosition($pos);
|
||||
$pk->pitch = $pitch;
|
||||
$pk->headYaw = $yaw;
|
||||
@@ -748,16 +749,17 @@ class NetworkSession{
|
||||
}
|
||||
|
||||
public function syncViewAreaCenterPoint(Vector3 $newPos, int $viewDistance) : void{
|
||||
$this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create($newPos->getFloorX(), $newPos->getFloorY(), $newPos->getFloorZ(), $viewDistance * 16)); //blocks, not chunks >.>
|
||||
$this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create(BlockPosition::fromVector3($newPos), $viewDistance * 16)); //blocks, not chunks >.>
|
||||
}
|
||||
|
||||
public function syncPlayerSpawnPoint(Position $newSpawn) : void{
|
||||
[$x, $y, $z] = [$newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ()];
|
||||
$this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z));
|
||||
$newSpawnBlockPosition = BlockPosition::fromVector3($newSpawn);
|
||||
//TODO: respawn causing block position (bed, respawn anchor)
|
||||
$this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawnBlockPosition, DimensionIds::OVERWORLD, $newSpawnBlockPosition));
|
||||
}
|
||||
|
||||
public function syncWorldSpawnPoint(Position $newSpawn) : void{
|
||||
$this->sendDataPacket(SetSpawnPositionPacket::worldSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), DimensionIds::OVERWORLD));
|
||||
$this->sendDataPacket(SetSpawnPositionPacket::worldSpawn(BlockPosition::fromVector3($newSpawn), DimensionIds::OVERWORLD));
|
||||
}
|
||||
|
||||
public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{
|
||||
@@ -788,7 +790,7 @@ class NetworkSession{
|
||||
$isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR);
|
||||
$pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL);
|
||||
$pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER);
|
||||
$pk->entityUniqueId = $for->getId();
|
||||
$pk->targetActorUniqueId = $for->getId();
|
||||
|
||||
$this->sendDataPacket($pk);
|
||||
}
|
||||
@@ -966,12 +968,12 @@ class NetworkSession{
|
||||
public function onMobMainHandItemChange(Human $mob) : void{
|
||||
//TODO: we could send zero for slot here because remote players don't need to know which slot was selected
|
||||
$inv = $mob->getInventory();
|
||||
$this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())), $inv->getHeldItemIndex(), ContainerIds::INVENTORY));
|
||||
$this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())), $inv->getHeldItemIndex(), $inv->getHeldItemIndex(), ContainerIds::INVENTORY));
|
||||
}
|
||||
|
||||
public function onMobOffHandItemChange(Human $mob) : void{
|
||||
$inv = $mob->getOffHandInventory();
|
||||
$this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))), 0, ContainerIds::OFFHAND));
|
||||
$this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))), 0, 0, ContainerIds::OFFHAND));
|
||||
}
|
||||
|
||||
public function onMobArmorChange(Living $mob) : void{
|
||||
|
6
src/network/mcpe/cache/CraftingDataCache.php
vendored
6
src/network/mcpe/cache/CraftingDataCache.php
vendored
@@ -79,7 +79,7 @@ final class CraftingDataCache{
|
||||
$converter = TypeConverter::getInstance();
|
||||
foreach($manager->getShapelessRecipes() as $list){
|
||||
foreach($list as $recipe){
|
||||
$pk->entries[] = new ProtocolShapelessRecipe(
|
||||
$pk->recipesWithTypeIds[] = new ProtocolShapelessRecipe(
|
||||
CraftingDataPacket::ENTRY_SHAPELESS,
|
||||
Binary::writeInt(++$counter),
|
||||
array_map(function(Item $item) use ($converter) : RecipeIngredient{
|
||||
@@ -104,7 +104,7 @@ final class CraftingDataCache{
|
||||
$inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row));
|
||||
}
|
||||
}
|
||||
$pk->entries[] = $r = new ProtocolShapedRecipe(
|
||||
$pk->recipesWithTypeIds[] = $r = new ProtocolShapedRecipe(
|
||||
CraftingDataPacket::ENTRY_SHAPED,
|
||||
Binary::writeInt(++$counter),
|
||||
$inputs,
|
||||
@@ -128,7 +128,7 @@ final class CraftingDataCache{
|
||||
};
|
||||
foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){
|
||||
$input = $converter->coreItemStackToNet($recipe->getInput());
|
||||
$pk->entries[] = new ProtocolFurnaceRecipe(
|
||||
$pk->recipesWithTypeIds[] = new ProtocolFurnaceRecipe(
|
||||
CraftingDataPacket::ENTRY_FURNACE_DATA,
|
||||
$input->getId(),
|
||||
$input->getMeta(),
|
||||
|
@@ -199,13 +199,13 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleActorEvent(ActorEventPacket $packet) : bool{
|
||||
if($packet->entityRuntimeId !== $this->player->getId()){
|
||||
if($packet->actorRuntimeId !== $this->player->getId()){
|
||||
//TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier)
|
||||
return $packet->event === ActorEventPacket::EATING_ITEM;
|
||||
return $packet->actorRuntimeId === ActorEventPacket::EATING_ITEM;
|
||||
}
|
||||
$this->player->doCloseInventory();
|
||||
|
||||
switch($packet->event){
|
||||
switch($packet->eventId){
|
||||
case ActorEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side
|
||||
$item = $this->player->getInventory()->getItemInHand();
|
||||
if($item->isNull()){
|
||||
@@ -356,12 +356,12 @@ class InGamePacketHandler extends PacketHandler{
|
||||
switch($data->getActionType()){
|
||||
case UseItemTransactionData::ACTION_CLICK_BLOCK:
|
||||
//TODO: start hack for client spam bug
|
||||
$clickPos = $data->getClickPos();
|
||||
$clickPos = $data->getClickPosition();
|
||||
$spamBug = ($this->lastRightClickData !== null and
|
||||
microtime(true) - $this->lastRightClickTime < 0.1 and //100ms
|
||||
$this->lastRightClickData->getPlayerPos()->distanceSquared($data->getPlayerPos()) < 0.00001 and
|
||||
$this->lastRightClickData->getBlockPos()->equals($data->getBlockPos()) and
|
||||
$this->lastRightClickData->getClickPos()->distanceSquared($clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error
|
||||
$this->lastRightClickData->getPlayerPosition()->distanceSquared($data->getPlayerPosition()) < 0.00001 and
|
||||
$this->lastRightClickData->getBlockPosition()->equals($data->getBlockPosition()) and
|
||||
$this->lastRightClickData->getClickPosition()->distanceSquared($clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error
|
||||
);
|
||||
//get rid of continued spam if the player clicks and holds right-click
|
||||
$this->lastRightClickData = $data;
|
||||
@@ -371,9 +371,10 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
//TODO: end hack for client spam bug
|
||||
|
||||
$blockPos = $data->getBlockPos();
|
||||
if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){
|
||||
$this->onFailedBlockAction($blockPos, $data->getFace());
|
||||
$blockPos = $data->getBlockPosition();
|
||||
$vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ());
|
||||
if(!$this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos)){
|
||||
$this->onFailedBlockAction($vBlockPos, $data->getFace());
|
||||
}elseif(
|
||||
!array_key_exists($windowId = InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, $this->openHardcodedWindows) &&
|
||||
$this->player->getCraftingGrid()->getGridWidth() === CraftingGrid::SIZE_BIG
|
||||
@@ -381,7 +382,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
//TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack
|
||||
//allows it to carry on working approximately the same way as it did in 1.14
|
||||
$this->openHardcodedWindows[$windowId] = true;
|
||||
$this->session->sendDataPacket(ContainerOpenPacket::blockInvVec3(
|
||||
$this->session->sendDataPacket(ContainerOpenPacket::blockInv(
|
||||
InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID,
|
||||
WindowTypes::WORKBENCH,
|
||||
$blockPos
|
||||
@@ -389,9 +390,10 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
return true;
|
||||
case UseItemTransactionData::ACTION_BREAK_BLOCK:
|
||||
$blockPos = $data->getBlockPos();
|
||||
if(!$this->player->breakBlock($blockPos)){
|
||||
$this->onFailedBlockAction($blockPos, null);
|
||||
$blockPos = $data->getBlockPosition();
|
||||
$vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ());
|
||||
if(!$this->player->breakBlock($vBlockPos)){
|
||||
$this->onFailedBlockAction($vBlockPos, null);
|
||||
}
|
||||
return true;
|
||||
case UseItemTransactionData::ACTION_CLICK_AIR:
|
||||
@@ -432,7 +434,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{
|
||||
$target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId());
|
||||
$target = $this->player->getWorld()->getEntity($data->getActorRuntimeId());
|
||||
if($target === null){
|
||||
return false;
|
||||
}
|
||||
@@ -442,7 +444,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
//TODO: use transactiondata for rollbacks here
|
||||
switch($data->getActionType()){
|
||||
case UseItemOnEntityTransactionData::ACTION_INTERACT:
|
||||
if(!$this->player->interactEntity($target, $data->getClickPos())){
|
||||
if(!$this->player->interactEntity($target, $data->getClickPosition())){
|
||||
$this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex());
|
||||
}
|
||||
return true;
|
||||
@@ -498,7 +500,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
//TODO: implement handling for this where it matters
|
||||
return true;
|
||||
}
|
||||
$target = $this->player->getWorld()->getEntity($packet->target);
|
||||
$target = $this->player->getWorld()->getEntity($packet->targetActorRuntimeId);
|
||||
if($target === null){
|
||||
return false;
|
||||
}
|
||||
@@ -521,7 +523,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{
|
||||
return $this->player->pickBlock(new Vector3($packet->blockX, $packet->blockY, $packet->blockZ), $packet->addUserData);
|
||||
return $this->player->pickBlock(new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ()), $packet->addUserData);
|
||||
}
|
||||
|
||||
public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{
|
||||
@@ -529,7 +531,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handlePlayerAction(PlayerActionPacket $packet) : bool{
|
||||
$pos = new Vector3($packet->x, $packet->y, $packet->z);
|
||||
$pos = new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ());
|
||||
|
||||
switch($packet->action){
|
||||
case PlayerActionPacket::ACTION_START_BREAK:
|
||||
@@ -628,7 +630,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{
|
||||
if($packet->entityUniqueId !== $this->player->getId()){
|
||||
if($packet->targetActorUniqueId !== $this->player->getId()){
|
||||
return false; //TODO: operators can change other people's permissions using this
|
||||
}
|
||||
|
||||
@@ -648,13 +650,13 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
|
||||
$pos = new Vector3($packet->x, $packet->y, $packet->z);
|
||||
$pos = new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ());
|
||||
if($pos->distanceSquared($this->player->getLocation()) > 10000){
|
||||
return false;
|
||||
}
|
||||
|
||||
$block = $this->player->getLocation()->getWorld()->getBlock($pos);
|
||||
$nbt = $packet->namedtag->getRoot();
|
||||
$nbt = $packet->nbt->getRoot();
|
||||
if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit
|
||||
|
||||
if($block instanceof BaseSign){
|
||||
@@ -678,7 +680,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->namedtag->getEncodedNbt()));
|
||||
$this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->nbt->getEncodedNbt()));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -712,9 +714,10 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{
|
||||
$block = $this->player->getWorld()->getBlockAt($packet->x, $packet->y, $packet->z);
|
||||
$blockPosition = $packet->blockPosition;
|
||||
$block = $this->player->getWorld()->getBlockAt($blockPosition->getX(), $blockPosition->getY(), $blockPosition->getZ());
|
||||
if($block instanceof ItemFrame and $block->getFramedItem() !== null){
|
||||
return $this->player->attackBlock(new Vector3($packet->x, $packet->y, $packet->z), $block->getFacing());
|
||||
return $this->player->attackBlock(new Vector3($blockPosition->getX(), $blockPosition->getY(), $blockPosition->getZ()), $block->getFacing());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -31,9 +31,11 @@ use pocketmine\network\mcpe\InventoryManager;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\mcpe\protocol\StartGamePacket;
|
||||
use pocketmine\network\mcpe\protocol\types\BlockPosition;
|
||||
use pocketmine\network\mcpe\protocol\types\BoolGameRule;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\protocol\types\Experiments;
|
||||
use pocketmine\network\mcpe\protocol\types\LevelSettings;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerMovementType;
|
||||
use pocketmine\network\mcpe\protocol\types\SpawnSettings;
|
||||
@@ -64,39 +66,46 @@ class PreSpawnPacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function setUp() : void{
|
||||
$spawnPosition = $this->player->getSpawn();
|
||||
$location = $this->player->getLocation();
|
||||
|
||||
$pk = new StartGamePacket();
|
||||
$pk->entityUniqueId = $this->player->getId();
|
||||
$pk->entityRuntimeId = $this->player->getId();
|
||||
$pk->playerGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode());
|
||||
$pk->playerPosition = $this->player->getOffsetPosition($location);
|
||||
$pk->pitch = $location->pitch;
|
||||
$pk->yaw = $location->yaw;
|
||||
$pk->seed = -1;
|
||||
$pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly
|
||||
$pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode());
|
||||
$pk->difficulty = $location->getWorld()->getDifficulty();
|
||||
$pk->spawnX = $spawnPosition->getFloorX();
|
||||
$pk->spawnY = $spawnPosition->getFloorY();
|
||||
$pk->spawnZ = $spawnPosition->getFloorZ();
|
||||
$pk->hasAchievementsDisabled = true;
|
||||
$pk->time = $location->getWorld()->getTime();
|
||||
$pk->eduEditionOffer = 0;
|
||||
$pk->rainLevel = 0; //TODO: implement these properly
|
||||
$pk->lightningLevel = 0;
|
||||
$pk->commandsEnabled = true;
|
||||
$pk->gameRules = [
|
||||
$levelSettings = new LevelSettings();
|
||||
$levelSettings->seed = -1;
|
||||
$levelSettings->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly
|
||||
$levelSettings->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode());
|
||||
$levelSettings->difficulty = $location->getWorld()->getDifficulty();
|
||||
$levelSettings->spawnPosition = BlockPosition::fromVector3($location->getWorld()->getSpawnLocation());
|
||||
$levelSettings->hasAchievementsDisabled = true;
|
||||
$levelSettings->time = $location->getWorld()->getTime();
|
||||
$levelSettings->eduEditionOffer = 0;
|
||||
$levelSettings->rainLevel = 0; //TODO: implement these properly
|
||||
$levelSettings->lightningLevel = 0;
|
||||
$levelSettings->commandsEnabled = true;
|
||||
$levelSettings->gameRules = [
|
||||
"naturalregeneration" => new BoolGameRule(false, false) //Hack for client side regeneration
|
||||
];
|
||||
$pk->experiments = new Experiments([], false);
|
||||
$pk->levelId = "";
|
||||
$pk->worldName = $this->server->getMotd();
|
||||
$pk->itemTable = GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries(); //TODO: check if this is actually needed
|
||||
$pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false);
|
||||
$pk->serverSoftwareVersion = sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true));
|
||||
$this->session->sendDataPacket($pk);
|
||||
$levelSettings->experiments = new Experiments([], false);
|
||||
|
||||
$this->session->sendDataPacket(StartGamePacket::create(
|
||||
$this->player->getId(),
|
||||
$this->player->getId(),
|
||||
TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode()),
|
||||
$this->player->getOffsetPosition($location),
|
||||
$location->pitch,
|
||||
$location->yaw,
|
||||
$levelSettings,
|
||||
"",
|
||||
$this->server->getMotd(),
|
||||
"",
|
||||
false,
|
||||
new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false),
|
||||
0,
|
||||
0,
|
||||
"",
|
||||
false,
|
||||
sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)),
|
||||
[],
|
||||
GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries()
|
||||
));
|
||||
|
||||
$this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers());
|
||||
$this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs());
|
||||
|
@@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\handler;
|
||||
|
||||
use pocketmine\lang\KnownTranslationKeys;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket;
|
||||
@@ -34,6 +35,7 @@ use pocketmine\network\mcpe\protocol\ResourcePackStackPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\Experiments;
|
||||
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType;
|
||||
use pocketmine\resourcepacks\ResourcePack;
|
||||
use pocketmine\resourcepacks\ResourcePackManager;
|
||||
use function array_map;
|
||||
@@ -113,7 +115,9 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
||||
self::PACK_CHUNK_SIZE,
|
||||
(int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE),
|
||||
$pack->getPackSize(),
|
||||
$pack->getSha256()
|
||||
$pack->getSha256(),
|
||||
false,
|
||||
ResourcePackType::ADDON //TODO: this might be an addon (not behaviour pack), needed to properly support client-side custom items
|
||||
));
|
||||
}
|
||||
$this->session->getLogger()->debug("Player requested download of " . count($packet->packIds) . " resource packs");
|
||||
@@ -130,7 +134,7 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
||||
//we don't force here, because it doesn't have user-facing effects
|
||||
//but it does have an annoying side-effect when true: it makes
|
||||
//the client remove its own non-server-supplied resource packs.
|
||||
$this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, new Experiments([], false)));
|
||||
$this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, ProtocolInfo::MINECRAFT_VERSION_NETWORK, new Experiments([], false)));
|
||||
$this->session->getLogger()->debug("Applying resource pack stack");
|
||||
break;
|
||||
case ResourcePackClientResponsePacket::STATUS_COMPLETED:
|
||||
|
Reference in New Issue
Block a user