PocketMine-MP 5.39.3 git-400eb2dddf91a9c112aa09f3b498ffc8c85e98ed
Loading...
Searching...
No Matches
StandardEntityEventBroadcaster.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\network\mcpe;
25
47use function array_map;
48use function count;
49use function ksort;
50use const SORT_NUMERIC;
51
53
54 public function __construct(
55 private PacketBroadcaster $broadcaster,
56 private TypeConverter $typeConverter
57 ){}
58
62 private function sendDataPacket(array $recipients, ClientboundPacket $packet) : void{
63 $this->broadcaster->broadcastPackets($recipients, [$packet]);
64 }
65
66 public function syncAttributes(array $recipients, Living $entity, array $attributes) : void{
67 if(count($attributes) > 0){
68 $this->sendDataPacket($recipients, UpdateAttributesPacket::create(
69 $entity->getId(),
70 array_map(fn(Attribute $attr) => new UpdateAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getDefaultValue(), []), $attributes),
71 0
72 ));
73 }
74 }
75
76 public function syncActorData(array $recipients, Entity $entity, array $properties) : void{
77 //TODO: HACK! as of 1.18.10, the client responds differently to the same data ordered in different orders - for
78 //example, sending HEIGHT in the list before FLAGS when unsetting the SWIMMING flag results in a hitbox glitch
79 ksort($properties, SORT_NUMERIC);
80 $this->sendDataPacket($recipients, SetActorDataPacket::create($entity->getId(), $properties, new PropertySyncData([], []), 0));
81 }
82
83 public function onEntityEffectAdded(array $recipients, Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{
84 //TODO: we may need yet another effect <=> ID map in the future depending on protocol changes
85 $this->sendDataPacket($recipients, MobEffectPacket::add(
86 $entity->getId(),
87 $replacesOldEffect,
88 EffectIdMap::getInstance()->toId($effect->getType()),
89 $effect->getAmplifier(),
90 $effect->isVisible(),
91 $effect->isInfinite() ? -1 : $effect->getDuration(),
92 tick: 0,
93 ambient: $effect->isAmbient()
94 ));
95 }
96
97 public function onEntityEffectRemoved(array $recipients, Living $entity, EffectInstance $effect) : void{
98 $this->sendDataPacket($recipients, MobEffectPacket::remove($entity->getId(), EffectIdMap::getInstance()->toId($effect->getType()), tick: 0));
99 }
100
101 public function onEntityRemoved(array $recipients, Entity $entity) : void{
102 $this->sendDataPacket($recipients, RemoveActorPacket::create($entity->getId()));
103 }
104
105 public function onMobMainHandItemChange(array $recipients, Human $mob) : void{
106 //TODO: we could send zero for slot here because remote players don't need to know which slot was selected
107 $inv = $mob->getInventory();
108 $this->sendDataPacket($recipients, MobEquipmentPacket::create(
109 $mob->getId(),
110 ItemStackWrapper::legacy($this->typeConverter->coreItemStackToNet($inv->getItemInHand())),
111 $inv->getHeldItemIndex(),
112 $inv->getHeldItemIndex(),
113 ContainerIds::INVENTORY
114 ));
115 }
116
117 public function onMobOffHandItemChange(array $recipients, Human $mob) : void{
118 $inv = $mob->getOffHandInventory();
119 $this->sendDataPacket($recipients, MobEquipmentPacket::create(
120 $mob->getId(),
121 ItemStackWrapper::legacy($this->typeConverter->coreItemStackToNet($inv->getItem(0))),
122 0,
123 0,
124 ContainerIds::OFFHAND
125 ));
126 }
127
128 public function onMobArmorChange(array $recipients, Living $mob) : void{
129 $inv = $mob->getArmorInventory();
130 $converter = $this->typeConverter;
131 $this->sendDataPacket($recipients, MobArmorEquipmentPacket::create(
132 $mob->getId(),
133 ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getHelmet())),
134 ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getChestplate())),
135 ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getLeggings())),
136 ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getBoots())),
137 new ItemStackWrapper(0, ItemStack::null())
138 ));
139 }
140
141 public function onPickUpItem(array $recipients, Entity $collector, Entity $pickedUp) : void{
142 $this->sendDataPacket($recipients, TakeItemActorPacket::create($collector->getId(), $pickedUp->getId()));
143 }
144
145 public function onEmote(array $recipients, Human $from, string $emoteId) : void{
146 $this->sendDataPacket($recipients, EmotePacket::create(
147 $from->getId(),
148 $emoteId,
149 0, //seems to be irrelevant for the client, we cannot risk rebroadcasting random values received
150 "",
151 "",
152 EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT
153 ));
154 }
155}
onEntityEffectAdded(array $recipients, Living $entity, EffectInstance $effect, bool $replacesOldEffect)
syncAttributes(array $recipients, Living $entity, array $attributes)
onEmote(array $recipients, Human $from, string $emoteId)
syncActorData(array $recipients, Entity $entity, array $properties)
onEntityEffectRemoved(array $recipients, Living $entity, EffectInstance $effect)
onPickUpItem(array $recipients, Entity $collector, Entity $pickedUp)
static create(int $actorRuntimeId, array $metadata, PropertySyncData $syncedProperties, int $tick)
static create(int $actorRuntimeId, array $entries, int $tick)