mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
First look at shared EntityEventBroadcaster,
this improves performance in PvP servers and other areas where lots of players or entities exist in one space. fixes #5622
This commit is contained in:
parent
e7e19abe85
commit
cc8660629b
@ -56,6 +56,7 @@ use pocketmine\network\mcpe\compression\Compressor;
|
||||
use pocketmine\network\mcpe\compression\ZlibCompressor;
|
||||
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
|
||||
use pocketmine\network\mcpe\encryption\EncryptionContext;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\PacketBroadcaster;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
@ -63,6 +64,7 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\raklib\RakLibInterface;
|
||||
use pocketmine\network\mcpe\StandardEntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\StandardPacketBroadcaster;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\network\NetworkInterfaceStartException;
|
||||
@ -1172,10 +1174,18 @@ class Server{
|
||||
return !$anyWorldFailedToLoad;
|
||||
}
|
||||
|
||||
private function startupPrepareConnectableNetworkInterfaces(string $ip, int $port, bool $ipV6, bool $useQuery, PacketBroadcaster $packetBroadcaster, PacketSerializerContext $packetSerializerContext) : bool{
|
||||
private function startupPrepareConnectableNetworkInterfaces(
|
||||
string $ip,
|
||||
int $port,
|
||||
bool $ipV6,
|
||||
bool $useQuery,
|
||||
PacketBroadcaster $packetBroadcaster,
|
||||
EntityEventBroadcaster $entityEventBroadcaster,
|
||||
PacketSerializerContext $packetSerializerContext
|
||||
) : bool{
|
||||
$prettyIp = $ipV6 ? "[$ip]" : $ip;
|
||||
try{
|
||||
$rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6, $packetBroadcaster, $packetSerializerContext));
|
||||
$rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext));
|
||||
}catch(NetworkInterfaceStartException $e){
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_networkStartFailed(
|
||||
$ip,
|
||||
@ -1202,13 +1212,14 @@ class Server{
|
||||
$useQuery = $this->configGroup->getConfigBool("enable-query", true);
|
||||
|
||||
$packetSerializerContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary());
|
||||
$broadcaster = new StandardPacketBroadcaster($this, $packetSerializerContext);
|
||||
$packetBroadcaster = new StandardPacketBroadcaster($this, $packetSerializerContext);
|
||||
$entityEventBroadcaster = new StandardEntityEventBroadcaster($packetBroadcaster);
|
||||
|
||||
if(
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery, $broadcaster, $packetSerializerContext) ||
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext) ||
|
||||
(
|
||||
$this->configGroup->getConfigBool("enable-ipv6", true) &&
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery, $broadcaster, $packetSerializerContext)
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext)
|
||||
)
|
||||
){
|
||||
return false;
|
||||
|
@ -44,6 +44,8 @@ use pocketmine\nbt\tag\DoubleTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\protocol\AddActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
|
||||
@ -1537,7 +1539,7 @@ abstract class Entity{
|
||||
$id = spl_object_id($player);
|
||||
if(isset($this->hasSpawned[$id])){
|
||||
if($send){
|
||||
$player->getNetworkSession()->onEntityRemoved($this);
|
||||
$player->getNetworkSession()->getEntityEventBroadcaster()->onEntityRemoved([$player->getNetworkSession()], $this);
|
||||
}
|
||||
unset($this->hasSpawned[$id]);
|
||||
}
|
||||
@ -1548,9 +1550,11 @@ abstract class Entity{
|
||||
* player moves, viewers will once again be able to see the entity.
|
||||
*/
|
||||
public function despawnFromAll() : void{
|
||||
foreach($this->hasSpawned as $player){
|
||||
$this->despawnFrom($player);
|
||||
}
|
||||
NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->hasSpawned,
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onEntityRemoved($recipients, $this)
|
||||
);
|
||||
$this->hasSpawned = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1624,9 +1628,7 @@ abstract class Entity{
|
||||
$targets = $targets ?? $this->hasSpawned;
|
||||
$data = $data ?? $this->getAllNetworkData();
|
||||
|
||||
foreach($targets as $p){
|
||||
$p->getNetworkSession()->syncActorData($this, $data);
|
||||
}
|
||||
NetworkBroadcastUtils::broadcastEntityEvent($targets, fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->syncActorData($recipients, $this, $data));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,6 +47,8 @@ use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
|
||||
use pocketmine\network\mcpe\convert\TypeConverter;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
|
||||
@ -189,9 +191,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
public function emote(string $emoteId) : void{
|
||||
foreach($this->getViewers() as $player){
|
||||
$player->getNetworkSession()->onEmote($this, $emoteId);
|
||||
}
|
||||
NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onEmote($recipients, $this, $emoteId)
|
||||
);
|
||||
}
|
||||
|
||||
public function getHungerManager() : HungerManager{
|
||||
@ -270,11 +273,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
$this->xpManager = new ExperienceManager($this);
|
||||
|
||||
$this->inventory = new PlayerInventory($this);
|
||||
$syncHeldItem = function() : void{
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobMainHandItemChange($this);
|
||||
}
|
||||
};
|
||||
$syncHeldItem = fn() => NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onMobMainHandItemChange($recipients, $this)
|
||||
);
|
||||
$this->inventory->getListeners()->add(new CallbackInventoryListener(
|
||||
function(Inventory $unused, int $slot, Item $unused2) use ($syncHeldItem) : void{
|
||||
if($slot === $this->inventory->getHeldItemIndex()){
|
||||
@ -315,11 +317,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
if($offHand !== null){
|
||||
$this->offHandInventory->setItem(0, Item::nbtDeserialize($offHand));
|
||||
}
|
||||
$this->offHandInventory->getListeners()->add(CallbackInventoryListener::onAnyChange(function() : void{
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobOffHandItemChange($this);
|
||||
}
|
||||
}));
|
||||
$this->offHandInventory->getListeners()->add(CallbackInventoryListener::onAnyChange(fn() => NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onMobOffHandItemChange($recipients, $this)
|
||||
)));
|
||||
|
||||
$enderChestInventoryTag = $nbt->getListTag(self::TAG_ENDER_CHEST_INVENTORY);
|
||||
if($enderChestInventoryTag !== null){
|
||||
@ -333,11 +334,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
$this->inventory->setHeldItemIndex($nbt->getInt(self::TAG_SELECTED_INVENTORY_SLOT, 0));
|
||||
$this->inventory->getHeldItemIndexChangeListeners()->add(function(int $oldIndex) : void{
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobMainHandItemChange($this);
|
||||
}
|
||||
});
|
||||
$this->inventory->getHeldItemIndexChangeListeners()->add(fn() => NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onMobMainHandItemChange($recipients, $this)
|
||||
));
|
||||
|
||||
$this->hungerManager->setFood((float) $nbt->getInt(self::TAG_FOOD_LEVEL, (int) $this->hungerManager->getFood()));
|
||||
$this->hungerManager->setExhaustion($nbt->getFloat(self::TAG_FOOD_EXHAUSTION_LEVEL, $this->hungerManager->getExhaustion()));
|
||||
@ -490,11 +490,12 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
protected function sendSpawnPacket(Player $player) : void{
|
||||
$networkSession = $player->getNetworkSession();
|
||||
if(!($this instanceof Player)){
|
||||
$player->getNetworkSession()->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), SkinAdapterSingleton::get()->toSkinData($this->skin))]));
|
||||
$networkSession->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), SkinAdapterSingleton::get()->toSkinData($this->skin))]));
|
||||
}
|
||||
|
||||
$player->getNetworkSession()->sendDataPacket(AddPlayerPacket::create(
|
||||
$networkSession->sendDataPacket(AddPlayerPacket::create(
|
||||
$this->getUniqueId(),
|
||||
$this->getName(),
|
||||
$this->getId(),
|
||||
@ -524,11 +525,12 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
//TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately
|
||||
$this->sendData([$player], [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]);
|
||||
|
||||
$player->getNetworkSession()->onMobArmorChange($this);
|
||||
$player->getNetworkSession()->onMobOffHandItemChange($this);
|
||||
$entityEventBroadcaster = $networkSession->getEntityEventBroadcaster();
|
||||
$entityEventBroadcaster->onMobArmorChange([$networkSession], $this);
|
||||
$entityEventBroadcaster->onMobOffHandItemChange([$networkSession], $this);
|
||||
|
||||
if(!($this instanceof Player)){
|
||||
$player->getNetworkSession()->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)]));
|
||||
$networkSession->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,8 @@ use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
|
||||
@ -143,13 +145,10 @@ abstract class Living extends Entity{
|
||||
|
||||
$this->armorInventory = new ArmorInventory($this);
|
||||
//TODO: load/save armor inventory contents
|
||||
$this->armorInventory->getListeners()->add(CallbackInventoryListener::onAnyChange(
|
||||
function(Inventory $unused) : void{
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobArmorChange($this);
|
||||
}
|
||||
}
|
||||
));
|
||||
$this->armorInventory->getListeners()->add(CallbackInventoryListener::onAnyChange(fn() => NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onMobArmorChange($recipients, $this)
|
||||
)));
|
||||
|
||||
$health = $this->getMaxHealth();
|
||||
|
||||
@ -850,7 +849,8 @@ abstract class Living extends Entity{
|
||||
protected function sendSpawnPacket(Player $player) : void{
|
||||
parent::sendSpawnPacket($player);
|
||||
|
||||
$player->getNetworkSession()->onMobArmorChange($this);
|
||||
$networkSession = $player->getNetworkSession();
|
||||
$networkSession->getEntityEventBroadcaster()->onMobArmorChange([$networkSession], $this);
|
||||
}
|
||||
|
||||
protected function syncNetworkData(EntityMetadataCollection $properties) : void{
|
||||
|
@ -35,6 +35,8 @@ use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\convert\TypeConverter;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\protocol\AddItemActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
|
||||
@ -328,9 +330,10 @@ class ItemEntity extends Entity{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onPlayerPickUpItem($player, $this);
|
||||
}
|
||||
NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onPickUpItem($recipients, $player, $this)
|
||||
);
|
||||
|
||||
$inventory = $ev->getInventory();
|
||||
if($inventory !== null){
|
||||
|
@ -33,6 +33,8 @@ use pocketmine\event\entity\ProjectileHitEvent;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
|
||||
@ -196,9 +198,10 @@ class Arrow extends Projectile{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onPlayerPickUpItem($player, $this);
|
||||
}
|
||||
NetworkBroadcastUtils::broadcastEntityEvent(
|
||||
$this->getViewers(),
|
||||
fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onPickUpItem($recipients, $player, $this)
|
||||
);
|
||||
|
||||
$ev->getInventory()?->addItem($ev->getItem());
|
||||
$this->flagForDespawn();
|
||||
|
93
src/network/mcpe/EntityEventBroadcaster.php
Normal file
93
src/network/mcpe/EntityEventBroadcaster.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty;
|
||||
|
||||
/**
|
||||
* This class allows broadcasting entity events to many viewers on the server network.
|
||||
*/
|
||||
interface EntityEventBroadcaster{
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
* @param Attribute[] $attributes
|
||||
*/
|
||||
public function syncAttributes(array $recipients, Living $entity, array $attributes) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
* @param MetadataProperty[] $properties
|
||||
*
|
||||
* @phpstan-param array<int, MetadataProperty> $properties
|
||||
*/
|
||||
public function syncActorData(array $recipients, Entity $entity, array $properties) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onEntityEffectAdded(array $recipients, Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onEntityEffectRemoved(array $recipients, Living $entity, EffectInstance $effect) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onEntityRemoved(array $recipients, Entity $entity) : void;
|
||||
|
||||
/**
|
||||
* TODO: expand this to more than just humans
|
||||
*
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onMobMainHandItemChange(array $recipients,Human $mob) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onMobOffHandItemChange(array $recipients, Human $mob) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onMobArmorChange(array $recipients, Living $mob) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onPickUpItem(array $recipients, Entity $collector, Entity $pickedUp) : void;
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
public function onEmote(array $recipients, Human $from, string $emoteId) : void;
|
||||
}
|
54
src/network/mcpe/NetworkBroadcastUtils.php
Normal file
54
src/network/mcpe/NetworkBroadcastUtils.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\player\Player;
|
||||
use function spl_object_id;
|
||||
|
||||
final class NetworkBroadcastUtils{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player[] $recipients
|
||||
* @phpstan-param \Closure(EntityEventBroadcaster, array<int, NetworkSession>) : void $callback
|
||||
*/
|
||||
public static function broadcastEntityEvent(array $recipients, \Closure $callback) : void{
|
||||
$uniqueBroadcasters = [];
|
||||
$broadcasterTargets = [];
|
||||
|
||||
foreach($recipients as $recipient){
|
||||
$session = $recipient->getNetworkSession();
|
||||
$broadcaster = $session->getEntityEventBroadcaster();
|
||||
$uniqueBroadcasters[spl_object_id($broadcaster)] = $broadcaster;
|
||||
$broadcasterTargets[spl_object_id($broadcaster)][spl_object_id($session)] = $session;
|
||||
}
|
||||
|
||||
foreach($uniqueBroadcasters as $k => $broadcaster){
|
||||
$callback($broadcaster, $broadcasterTargets[$k]);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,12 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\data\bedrock\EffectIdMap;
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\event\player\PlayerDuplicateLoginEvent;
|
||||
use pocketmine\event\server\DataPacketReceiveEvent;
|
||||
use pocketmine\event\server\DataPacketSendEvent;
|
||||
@ -61,10 +56,6 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
||||
use pocketmine\network\mcpe\protocol\EmotePacket;
|
||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEffectPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
|
||||
@ -73,19 +64,16 @@ use pocketmine\network\mcpe\protocol\PacketDecodeException;
|
||||
use pocketmine\network\mcpe\protocol\PacketPool;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\protocol\ServerboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTimePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTitlePacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\TextPacket;
|
||||
use pocketmine\network\mcpe\protocol\ToastRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\TransferPacket;
|
||||
@ -97,16 +85,10 @@ use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandPermissions;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\PropertySyncData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAbilitiesPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAdventureSettingsPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
|
||||
use pocketmine\network\NetworkSessionManager;
|
||||
use pocketmine\network\PacketHandlingException;
|
||||
use pocketmine\permission\DefaultPermissionNames;
|
||||
@ -134,7 +116,6 @@ use function hrtime;
|
||||
use function in_array;
|
||||
use function intdiv;
|
||||
use function json_encode;
|
||||
use function ksort;
|
||||
use function min;
|
||||
use function strcasecmp;
|
||||
use function strlen;
|
||||
@ -143,7 +124,6 @@ use function substr;
|
||||
use function time;
|
||||
use function ucfirst;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
use const SORT_NUMERIC;
|
||||
|
||||
class NetworkSession{
|
||||
private const INCOMING_PACKET_BATCH_PER_TICK = 2; //usually max 1 per tick, but transactions may arrive separately
|
||||
@ -202,6 +182,7 @@ class NetworkSession{
|
||||
private PacketSerializerContext $packetSerializerContext,
|
||||
private PacketSender $sender,
|
||||
private PacketBroadcaster $broadcaster,
|
||||
private EntityEventBroadcaster $entityEventBroadcaster,
|
||||
private Compressor $compressor,
|
||||
private string $ip,
|
||||
private int $port
|
||||
@ -223,6 +204,7 @@ class NetworkSession{
|
||||
|
||||
$this->manager->add($this);
|
||||
$this->logger->info("Session opened");
|
||||
$this->entityEventBroadcaster = $entityEventBroadcaster;
|
||||
}
|
||||
|
||||
private function getLogPrefix() : string{
|
||||
@ -273,10 +255,10 @@ class NetworkSession{
|
||||
|
||||
$effectManager = $this->player->getEffects();
|
||||
$effectManager->getEffectAddHooks()->add($effectAddHook = function(EffectInstance $effect, bool $replacesOldEffect) : void{
|
||||
$this->onEntityEffectAdded($this->player, $effect, $replacesOldEffect);
|
||||
$this->entityEventBroadcaster->onEntityEffectAdded([$this], $this->player, $effect, $replacesOldEffect);
|
||||
});
|
||||
$effectManager->getEffectRemoveHooks()->add($effectRemoveHook = function(EffectInstance $effect) : void{
|
||||
$this->onEntityEffectRemoved($this->player, $effect);
|
||||
$this->entityEventBroadcaster->onEntityEffectRemoved([$this], $this->player, $effect);
|
||||
});
|
||||
$this->disposeHooks->add(static function() use ($effectManager, $effectAddHook, $effectRemoveHook) : void{
|
||||
$effectManager->getEffectAddHooks()->remove($effectAddHook);
|
||||
@ -547,6 +529,8 @@ class NetworkSession{
|
||||
|
||||
public function getBroadcaster() : PacketBroadcaster{ return $this->broadcaster; }
|
||||
|
||||
public function getEntityEventBroadcaster() : EntityEventBroadcaster{ return $this->entityEventBroadcaster; }
|
||||
|
||||
public function getCompressor() : Compressor{
|
||||
return $this->compressor;
|
||||
}
|
||||
@ -817,7 +801,7 @@ class NetworkSession{
|
||||
}
|
||||
|
||||
public function onServerRespawn() : void{
|
||||
$this->syncAttributes($this->player, $this->player->getAttributeMap()->getAll());
|
||||
$this->entityEventBroadcaster->syncAttributes([$this], $this->player, $this->player->getAttributeMap()->getAll());
|
||||
$this->player->sendData(null);
|
||||
|
||||
$this->syncAbilities($this->player);
|
||||
@ -926,41 +910,6 @@ class NetworkSession{
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute[] $attributes
|
||||
*/
|
||||
public function syncAttributes(Living $entity, array $attributes) : void{
|
||||
if(count($attributes) > 0){
|
||||
$this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), array_map(function(Attribute $attr) : NetworkAttribute{
|
||||
return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue(), []);
|
||||
}, $attributes), 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MetadataProperty[] $properties
|
||||
* @phpstan-param array<int, MetadataProperty> $properties
|
||||
*/
|
||||
public function syncActorData(Entity $entity, array $properties) : void{
|
||||
//TODO: HACK! as of 1.18.10, the client responds differently to the same data ordered in different orders - for
|
||||
//example, sending HEIGHT in the list before FLAGS when unsetting the SWIMMING flag results in a hitbox glitch
|
||||
ksort($properties, SORT_NUMERIC);
|
||||
$this->sendDataPacket(SetActorDataPacket::create($entity->getId(), $properties, new PropertySyncData([], []), 0));
|
||||
}
|
||||
|
||||
public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{
|
||||
//TODO: we may need yet another effect <=> ID map in the future depending on protocol changes
|
||||
$this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, EffectIdMap::getInstance()->toId($effect->getType()), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration()));
|
||||
}
|
||||
|
||||
public function onEntityEffectRemoved(Living $entity, EffectInstance $effect) : void{
|
||||
$this->sendDataPacket(MobEffectPacket::remove($entity->getId(), EffectIdMap::getInstance()->toId($effect->getType())));
|
||||
}
|
||||
|
||||
public function onEntityRemoved(Entity $entity) : void{
|
||||
$this->sendDataPacket(RemoveActorPacket::create($entity->getId()));
|
||||
}
|
||||
|
||||
public function syncAvailableCommands() : void{
|
||||
$commandData = [];
|
||||
foreach($this->server->getCommandMap()->getCommands() as $name => $command){
|
||||
@ -1096,36 +1045,6 @@ class NetworkSession{
|
||||
return $this->invManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: expand this to more than just humans
|
||||
*/
|
||||
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(), $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, 0, ContainerIds::OFFHAND));
|
||||
}
|
||||
|
||||
public function onMobArmorChange(Living $mob) : void{
|
||||
$inv = $mob->getArmorInventory();
|
||||
$converter = TypeConverter::getInstance();
|
||||
$this->sendDataPacket(MobArmorEquipmentPacket::create(
|
||||
$mob->getId(),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getHelmet())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getChestplate())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getLeggings())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getBoots()))
|
||||
));
|
||||
}
|
||||
|
||||
public function onPlayerPickUpItem(Player $collector, Entity $pickedUp) : void{
|
||||
$this->sendDataPacket(TakeItemActorPacket::create($collector->getId(), $pickedUp->getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player[] $players
|
||||
*/
|
||||
@ -1169,10 +1088,6 @@ class NetworkSession{
|
||||
$this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut));
|
||||
}
|
||||
|
||||
public function onEmote(Human $from, string $emoteId) : void{
|
||||
$this->sendDataPacket(EmotePacket::create($from->getId(), $emoteId, EmotePacket::FLAG_SERVER));
|
||||
}
|
||||
|
||||
public function onToastNotification(string $title, string $body) : void{
|
||||
$this->sendDataPacket(ToastRequestPacket::create($title, $body));
|
||||
}
|
||||
@ -1212,7 +1127,7 @@ class NetworkSession{
|
||||
$this->player->doChunkRequests();
|
||||
|
||||
$dirtyAttributes = $this->player->getAttributeMap()->needSend();
|
||||
$this->syncAttributes($this->player, $dirtyAttributes);
|
||||
$this->entityEventBroadcaster->syncAttributes([$this], $this->player, $dirtyAttributes);
|
||||
foreach($dirtyAttributes as $attribute){
|
||||
//TODO: we might need to send these to other players in the future
|
||||
//if that happens, this will need to become more complex than a flag on the attribute itself
|
||||
|
143
src/network/mcpe/StandardEntityEventBroadcaster.php
Normal file
143
src/network/mcpe/StandardEntityEventBroadcaster.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\data\bedrock\EffectIdMap;
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\network\mcpe\convert\TypeConverter;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\EmotePacket;
|
||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEffectPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\PropertySyncData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function ksort;
|
||||
use const SORT_NUMERIC;
|
||||
|
||||
final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{
|
||||
|
||||
public function __construct(
|
||||
private StandardPacketBroadcaster $broadcaster
|
||||
){}
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
*/
|
||||
private function sendDataPacket(array $recipients, ClientboundPacket $packet) : void{
|
||||
$this->broadcaster->broadcastPackets($recipients, [$packet]);
|
||||
}
|
||||
|
||||
public function syncAttributes(array $recipients, Living $entity, array $attributes) : void{
|
||||
if(count($attributes) > 0){
|
||||
$this->sendDataPacket($recipients, UpdateAttributesPacket::create(
|
||||
$entity->getId(),
|
||||
array_map(fn(Attribute $attr) => new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue(), []), $attributes),
|
||||
0
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function syncActorData(array $recipients, Entity $entity, array $properties) : void{
|
||||
//TODO: HACK! as of 1.18.10, the client responds differently to the same data ordered in different orders - for
|
||||
//example, sending HEIGHT in the list before FLAGS when unsetting the SWIMMING flag results in a hitbox glitch
|
||||
ksort($properties, SORT_NUMERIC);
|
||||
$this->sendDataPacket($recipients, SetActorDataPacket::create($entity->getId(), $properties, new PropertySyncData([], []), 0));
|
||||
}
|
||||
|
||||
public function onEntityEffectAdded(array $recipients, Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{
|
||||
//TODO: we may need yet another effect <=> ID map in the future depending on protocol changes
|
||||
$this->sendDataPacket($recipients, MobEffectPacket::add(
|
||||
$entity->getId(),
|
||||
$replacesOldEffect,
|
||||
EffectIdMap::getInstance()->toId($effect->getType()),
|
||||
$effect->getAmplifier(),
|
||||
$effect->isVisible(),
|
||||
$effect->getDuration()
|
||||
));
|
||||
}
|
||||
|
||||
public function onEntityEffectRemoved(array $recipients, Living $entity, EffectInstance $effect) : void{
|
||||
$this->sendDataPacket($recipients, MobEffectPacket::remove($entity->getId(), EffectIdMap::getInstance()->toId($effect->getType())));
|
||||
}
|
||||
|
||||
public function onEntityRemoved(array $recipients, Entity $entity) : void{
|
||||
$this->sendDataPacket($recipients, RemoveActorPacket::create($entity->getId()));
|
||||
}
|
||||
|
||||
public function onMobMainHandItemChange(array $recipients, 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($recipients, MobEquipmentPacket::create(
|
||||
$mob->getId(),
|
||||
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())),
|
||||
$inv->getHeldItemIndex(),
|
||||
$inv->getHeldItemIndex(),
|
||||
ContainerIds::INVENTORY
|
||||
));
|
||||
}
|
||||
|
||||
public function onMobOffHandItemChange(array $recipients, Human $mob) : void{
|
||||
$inv = $mob->getOffHandInventory();
|
||||
$this->sendDataPacket($recipients, MobEquipmentPacket::create(
|
||||
$mob->getId(),
|
||||
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))),
|
||||
0,
|
||||
0,
|
||||
ContainerIds::OFFHAND
|
||||
));
|
||||
}
|
||||
|
||||
public function onMobArmorChange(array $recipients, Living $mob) : void{
|
||||
$inv = $mob->getArmorInventory();
|
||||
$converter = TypeConverter::getInstance();
|
||||
$this->sendDataPacket($recipients, MobArmorEquipmentPacket::create(
|
||||
$mob->getId(),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getHelmet())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getChestplate())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getLeggings())),
|
||||
ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getBoots()))
|
||||
));
|
||||
}
|
||||
|
||||
public function onPickUpItem(array $recipients, Entity $collector, Entity $pickedUp) : void{
|
||||
$this->sendDataPacket($recipients, TakeItemActorPacket::create($collector->getId(), $pickedUp->getId()));
|
||||
}
|
||||
|
||||
public function onEmote(array $recipients, Human $from, string $emoteId) : void{
|
||||
$this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, EmotePacket::FLAG_SERVER));
|
||||
}
|
||||
}
|
@ -114,7 +114,7 @@ class PreSpawnPacketHandler extends PacketHandler{
|
||||
$this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs());
|
||||
|
||||
$this->session->getLogger()->debug("Sending attributes");
|
||||
$this->session->syncAttributes($this->player, $this->player->getAttributeMap()->getAll());
|
||||
$this->session->getEntityEventBroadcaster()->syncAttributes([$this->session], $this->player, $this->player->getAttributeMap()->getAll());
|
||||
|
||||
$this->session->getLogger()->debug("Sending available commands");
|
||||
$this->session->syncAvailableCommands();
|
||||
@ -125,7 +125,7 @@ class PreSpawnPacketHandler extends PacketHandler{
|
||||
|
||||
$this->session->getLogger()->debug("Sending effects");
|
||||
foreach($this->player->getEffects()->all() as $effect){
|
||||
$this->session->onEntityEffectAdded($this->player, $effect, false);
|
||||
$this->session->getEntityEventBroadcaster()->onEntityEffectAdded([$this->session], $this->player, $effect, false);
|
||||
}
|
||||
|
||||
$this->session->getLogger()->debug("Sending actor metadata");
|
||||
|
@ -25,14 +25,13 @@ namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pocketmine\network\AdvancedNetworkInterface;
|
||||
use pocketmine\network\mcpe\compression\ZlibCompressor;
|
||||
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
|
||||
use pocketmine\network\mcpe\convert\TypeConverter;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\PacketBroadcaster;
|
||||
use pocketmine\network\mcpe\protocol\PacketPool;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\StandardPacketBroadcaster;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\network\NetworkInterfaceStartException;
|
||||
use pocketmine\network\PacketHandlingException;
|
||||
@ -80,13 +79,15 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
|
||||
private SleeperNotifier $sleeper;
|
||||
|
||||
private PacketBroadcaster $broadcaster;
|
||||
private PacketBroadcaster $packetBroadcaster;
|
||||
private EntityEventBroadcaster $entityEventBroadcaster;
|
||||
private PacketSerializerContext $packetSerializerContext;
|
||||
|
||||
public function __construct(Server $server, string $ip, int $port, bool $ipV6, PacketBroadcaster $packetBroadcaster, PacketSerializerContext $packetSerializerContext){
|
||||
public function __construct(Server $server, string $ip, int $port, bool $ipV6, PacketBroadcaster $packetBroadcaster, EntityEventBroadcaster $entityEventBroadcaster, PacketSerializerContext $packetSerializerContext){
|
||||
$this->server = $server;
|
||||
$this->broadcaster = $packetBroadcaster;
|
||||
$this->packetBroadcaster = $packetBroadcaster;
|
||||
$this->packetSerializerContext = $packetSerializerContext;
|
||||
$this->entityEventBroadcaster = $entityEventBroadcaster;
|
||||
|
||||
$this->rakServerId = mt_rand(0, PHP_INT_MAX);
|
||||
|
||||
@ -172,7 +173,8 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
PacketPool::getInstance(),
|
||||
$this->packetSerializerContext,
|
||||
new RakLibPacketSender($sessionId, $this),
|
||||
$this->broadcaster,
|
||||
$this->packetBroadcaster,
|
||||
$this->entityEventBroadcaster,
|
||||
ZlibCompressor::getInstance(), //TODO: this shouldn't be hardcoded, but we might need the RakNet protocol version to select it
|
||||
$address,
|
||||
$port
|
||||
|
@ -490,11 +490,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/command/defaults/TimingsCommand.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/console/ConsoleReader.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
@ -650,21 +645,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectAdded\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectRemoved\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAttributes\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAbilities\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 2
|
||||
@ -685,6 +665,21 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\EntityEventBroadcaster\\:\\:onEntityEffectAdded\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\EntityEventBroadcaster\\:\\:onEntityEffectRemoved\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\EntityEventBroadcaster\\:\\:syncAttributes\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/NetworkSession.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$player of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\PreSpawnPacketHandler constructor expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#"
|
||||
count: 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user