Cuberite
A lightweight, fast and extensible game server for Minecraft
Protocol_1_11.cpp
Go to the documentation of this file.
1 
2 // Protocol_1_11.cpp
3 
4 /*
5 Implements the 1.11 protocol classes:
6  - cProtocol_1_11_0
7  - release 1.11 protocol (#315)
8  - cProtocol_1_11_1
9  - release 1.11.1 protocol (#316)
10 */
11 
12 #include "Globals.h"
13 #include "Protocol_1_11.h"
14 #include "Packetizer.h"
15 
16 #include "../WorldStorage/FastNBT.h"
17 
18 #include "../Entities/Boat.h"
19 #include "../Entities/EnderCrystal.h"
20 #include "../Entities/ExpOrb.h"
21 #include "../Entities/Minecart.h"
22 #include "../Entities/FallingBlock.h"
23 #include "../Entities/Painting.h"
24 #include "../Entities/Pickup.h"
25 #include "../Entities/Player.h"
26 #include "../Entities/ItemFrame.h"
27 #include "../Entities/ArrowEntity.h"
28 #include "../Entities/FireworkEntity.h"
29 #include "../Entities/SplashPotionEntity.h"
30 
31 #include "../Mobs/IncludeAllMonsters.h"
32 
33 #include "../BlockEntities/BedEntity.h"
34 #include "../BlockEntities/MobSpawnerEntity.h"
35 
36 #include "../Root.h"
37 #include "../Server.h"
38 #include "../ClientHandle.h"
39 #include "../CompositeChat.h"
40 #include "../JsonUtils.h"
41 #include "../Bindings/PluginManager.h"
42 
43 
44 
45 
46 
47 // The disabled error is intended, since the Metadata have overlapping indexes
48 // based on the type of the Entity.
49 //
50 // IMPORTANT: The enum is used to automate the sequential counting of the
51 // Metadata indexes. Adding a new enum value causes the following values to
52 // increase their index. Therefore the ordering of the enum values is VERY important!
53 #ifdef __clang__
54  #pragma clang diagnostic push
55  #pragma clang diagnostic ignored "-Wduplicate-enum"
56 #endif
57 
58 namespace Metadata_1_11
59 {
61  {
62  // Entity
69  _ENTITY_NEXT, // Used by descendants
70 
71  // Potion
72  POTION_THROWN = _ENTITY_NEXT,
73 
74  // FallingBlock
75  FALLING_BLOCK_POSITION = _ENTITY_NEXT,
76 
77  // AreaEffectCloud
78  AREA_EFFECT_CLOUD_RADIUS = _ENTITY_NEXT,
84 
85  // Arrow
86  ARROW_CRITICAL = _ENTITY_NEXT,
87  _ARROW_NEXT,
88 
89  // TippedArrow
90  TIPPED_ARROW_COLOR = _ARROW_NEXT,
91 
92  // Boat
93  BOAT_LAST_HIT_TIME = _ENTITY_NEXT,
99 
100  // EnderCrystal
103 
104  // Fireball
105  _FIREBALL_NEXT = _ENTITY_NEXT,
106 
107  // WitherSkull
108  WITHER_SKULL_INVULNERABLE = _FIREBALL_NEXT,
109 
110  // Fireworks
111  FIREWORK_INFO = _ENTITY_NEXT,
113 
114  // Hanging
115  _HANGING_NEXT = _ENTITY_NEXT,
116 
117  // ItemFrame
118  ITEM_FRAME_ITEM = _HANGING_NEXT,
120 
121  // Item
122  ITEM_ITEM = _ENTITY_NEXT,
123 
124  // Living
125  LIVING_ACTIVE_HAND = _ENTITY_NEXT,
130  _LIVING_NEXT,
131 
132  // Player
137 
138  // ArmorStand
139  ARMOR_STAND_STATUS = _LIVING_NEXT,
146 
147  // Insentient
148  INSENTIENT_STATUS = _LIVING_NEXT,
149  _INSENTIENT_NEXT,
150 
151  // Ambient
152  _AMBIENT_NEXT = _INSENTIENT_NEXT,
153 
154  // Bat
155  BAT_HANGING = _AMBIENT_NEXT,
156 
157  // Creature
158  _CREATURE_NEXT = _INSENTIENT_NEXT,
159 
160  // Ageable
161  AGEABLE_BABY = _CREATURE_NEXT,
162  _AGEABLE_NEXT,
163 
164  // PolarBear
165  POLAR_BEAR_STANDING = _AGEABLE_NEXT,
166 
167  // Animal
168  _ANIMAL_NEXT = _AGEABLE_NEXT,
169 
170  // Abstract horse
171  ABSTRACT_HORSE_STATUS = _ANIMAL_NEXT,
173  _ABSTRACT_HORSE_NEXT,
174 
175  // Horse
176  HORSE_VARIANT = _ABSTRACT_HORSE_NEXT,
178 
179  // Chested horse
180  CHESTED_HORSE_CHESTED = _ABSTRACT_HORSE_NEXT,
181  _CHESTED_HORSE_NEXT,
182 
183  // Llama
184  LLAMA_STRENGTH = _CHESTED_HORSE_NEXT,
187 
188  // Pig
189  PIG_HAS_SADDLE = _ANIMAL_NEXT,
191 
192  // Rabbit
193  RABBIT_TYPE = _ANIMAL_NEXT,
194 
195  // Sheep
196  SHEEP_STATUS = _ANIMAL_NEXT,
197 
198  // TameableAnimal
199  TAMEABLE_ANIMAL_STATUS = _ANIMAL_NEXT,
201  _TAMEABLE_NEXT,
202 
203  // Ocelot
204  OCELOT_TYPE = _TAMEABLE_NEXT,
205 
206  // Wolf
207  WOLF_DAMAGE_TAKEN = _TAMEABLE_NEXT,
210 
211  // Villager
212  VILLAGER_PROFESSION = _AGEABLE_NEXT,
213 
214  // Golem
215  _GOLEM_NEXT = _CREATURE_NEXT,
216 
217  // IronGolem
219 
220  // Shulker
224 
225  // Monster
226  _MONSTER_NEXT = _CREATURE_NEXT,
227 
228  // Blaze
229  BLAZE_ON_FIRE = _MONSTER_NEXT,
230 
231  // Creeper
232  CREEPER_STATE = _MONSTER_NEXT,
235 
236  // Guardian
237  GUARDIAN_STATUS = _MONSTER_NEXT,
239 
240  // Abstract Skeleton
242 
243  // Spider
244  SPIDER_CLIMBING = _MONSTER_NEXT,
245 
246  // Witch
247  WITCH_AGGRESIVE = _MONSTER_NEXT,
248 
249  // Wither
250  WITHER_FIRST_HEAD_TARGET = _MONSTER_NEXT,
254 
255  // Zombie
256  ZOMBIE_IS_BABY = _MONSTER_NEXT,
257  ZOMBIE_UNUSED, // Was type
259  _ZOMBIE_NEXT,
260 
261  // Zombie villager
264 
265  // Enderman
266  ENDERMAN_CARRIED_BLOCK = _MONSTER_NEXT,
268 
269  // Evocation illager
270  EVOKER_SPELL = _MONSTER_NEXT,
271 
272  // Vex
273  VEX_FLAGS = _MONSTER_NEXT,
274 
275  // Vindication illager
276  VINDICATOR_FLAGS = _MONSTER_NEXT,
277 
278  // EnderDragon
279  ENDER_DRAGON_DRAGON_PHASE = _INSENTIENT_NEXT,
280 
281  // Flying
282  _FLYING_NEXT = _INSENTIENT_NEXT,
283 
284  // Ghast
285  GHAST_ATTACKING = _FLYING_NEXT,
286 
287  // Slime
288  SLIME_SIZE = _INSENTIENT_NEXT,
289 
290  // Minecart
291  MINECART_SHAKING_POWER = _ENTITY_NEXT,
297  _MINECART_NEXT,
298 
299  // MinecartCommandBlock
302 
303  // MinecartFurnace
304  MINECART_FURNACE_POWERED = _MINECART_NEXT,
305 
306  // TNTPrimed
307  TNT_PRIMED_FUSE_TIME = _ENTITY_NEXT,
308  };
309 }
310 
311 #ifdef __clang__
312  #pragma clang diagnostic pop // Restore ignored clang errors
313 #endif
314 
315 
316 
317 
318 
320 // cProtocol_1_11_0:
321 
322 void cProtocol_1_11_0::SendCollectEntity(const cEntity & a_Collected, const cEntity & a_Collector, unsigned a_Count)
323 {
324  ASSERT(m_State == 3); // In game mode?
325 
326  cPacketizer Pkt(*this, pktCollectEntity);
327  Pkt.WriteVarInt32(a_Collected.GetUniqueID());
328  Pkt.WriteVarInt32(a_Collector.GetUniqueID());
329  Pkt.WriteVarInt32(static_cast<UInt32>(a_Count));
330 }
331 
332 
333 
334 
335 
336 void cProtocol_1_11_0::SendEntityAnimation(const cEntity & a_Entity, const EntityAnimation a_Animation)
337 {
338  switch (a_Animation)
339  {
342  {
343  // Vanilla stopped doing clientside prediction for thrown projectile particle effects (for some reason).
344  // But they're still doing motion prediction, and latency exists, hence re-send the server position to avoid particle effects happening inside a block:
345  SendEntityPosition(a_Entity);
346  break;
347  }
354  {
355  const auto Position = a_Entity.GetPosition();
356 
357  // 1.11 dropped the automatic particle effect + sound on item break. Emulate at least some of it:
358  SendSoundEffect("entity.item.break", Position, 1, 0.75f + ((a_Entity.GetUniqueID() * 23) % 32) / 64.f);
359  break;
360  }
361  default: break;
362  }
363 
364  Super::SendEntityAnimation(a_Entity, a_Animation);
365 }
366 
367 
368 
369 
370 
372 {
373  ASSERT(m_State == 3); // In game mode?
374 
375  cPacketizer Pkt(*this, pktTitle);
376  Pkt.WriteVarInt32(4); // Hide title
377 }
378 
379 
380 
381 
382 
384 {
385  ASSERT(m_State == 3); // In game mode?
386 
387  cPacketizer Pkt(*this, pktTitle);
388  Pkt.WriteVarInt32(5); // Reset title
389 }
390 
391 
392 
393 
394 
396 {
397  ASSERT(m_State == 3); // In game mode?
398 
399  const auto MobType = GetProtocolMobType(a_Mob.GetMobType());
400 
401  // If the type is not valid in this protocol bail out:
402  if (MobType == 0)
403  {
404  return;
405  }
406 
407  cPacketizer Pkt(*this, pktSpawnMob);
408  Pkt.WriteVarInt32(a_Mob.GetUniqueID());
409  // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
410  Pkt.WriteBEUInt64(0);
411  Pkt.WriteBEUInt64(a_Mob.GetUniqueID());
412  Pkt.WriteVarInt32(MobType);
413  Vector3d LastSentPos = a_Mob.GetLastSentPosition();
414  Pkt.WriteBEDouble(LastSentPos.x);
415  Pkt.WriteBEDouble(LastSentPos.y);
416  Pkt.WriteBEDouble(LastSentPos.z);
417  Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); // Doesn't seem to be used
418  Pkt.WriteByteAngle(a_Mob.GetPitch());
419  Pkt.WriteByteAngle(a_Mob.GetYaw());
420  Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400));
421  Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400));
422  Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedZ() * 400));
423  WriteEntityMetadata(Pkt, a_Mob);
424  Pkt.WriteBEUInt8(0xff); // Metadata terminator
425 }
426 
427 
428 
429 
430 
431 void cProtocol_1_11_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
432 {
433  ASSERT(m_State == 3); // In game mode?
434 
435  cPacketizer Pkt(*this, pktTitle);
436  Pkt.WriteVarInt32(3); // Set title display times
437  Pkt.WriteBEInt32(a_FadeInTicks);
438  Pkt.WriteBEInt32(a_DisplayTicks);
439  Pkt.WriteBEInt32(a_FadeOutTicks);
440 }
441 
442 
443 
444 
445 
447 {
448  ASSERT(m_State == 3); // In game mode?
449 
450  Byte Action;
451  switch (a_BlockEntity.GetBlockType())
452  {
453  case E_BLOCK_CHEST:
455  case E_BLOCK_END_PORTAL:
457  {
458  // The ones with a action of 0 is just a workaround to send the block entities to a client.
459  // Todo: 18.09.2020 - remove this when block entities are transmitted in the ChunkData packet - 12xx12
460  Action = 0;
461  break;
462  }
463 
464  case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
465  case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
466  case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity
467  case E_BLOCK_HEAD: Action = 4; break; // Update mobhead entity
468  case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot
469  case E_BLOCK_WALL_BANNER:
470  case E_BLOCK_STANDING_BANNER: Action = 6; break; // Update banner
471  case E_BLOCK_BED: Action = 11; break; // Update bed color (new!)
472 
473  default: return; // Block entities change between versions
474  }
475 
476  cPacketizer Pkt(*this, pktUpdateBlockEntity);
477  Pkt.WriteXYZPosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ());
478  Pkt.WriteBEUInt8(Action);
479 
480  cFastNBTWriter Writer;
481  WriteBlockEntity(Writer, a_BlockEntity);
482  Writer.Finish();
483  Pkt.WriteBuf(Writer.GetResult());
484 }
485 
486 
487 
488 
489 
490 signed char cProtocol_1_11_0::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
491 {
492  switch (a_Animation)
493  {
494  case EntityAnimation::EggCracks: return 3;
497  case EntityAnimation::PawnTotemActivates: return 35;
498  case EntityAnimation::SnowballPoofs: return 3;
499  default: return Super::GetProtocolEntityStatus(a_Animation);
500  }
501 }
502 
503 
504 
505 
506 
508 {
509  switch (a_MobType)
510  {
511  // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
512  case mtInvalidType: return 53;
513  case mtBat: return 65;
514  case mtBlaze: return 61;
515  case mtCaveSpider: return 59;
516  case mtChicken: return 93;
517  case mtCow: return 92;
518  case mtCreeper: return 50;
519  case mtDonkey: return 31;
520  case mtEnderDragon: return 63;
521  case mtEnderman: return 58;
522  case mtEndermite: return 67;
523  case mtEvoker: return 34;
524  case mtGhast: return 56;
525  case mtGiant: return 53;
526  case mtGuardian: return 68;
527  case mtHorse: return 100;
528  case mtHusk: return 23;
529  case mtIronGolem: return 99;
530  case mtLlama: return 103;
531  case mtMagmaCube: return 62;
532  case mtMooshroom: return 96;
533  case mtMule: return 32;
534  case mtOcelot: return 98;
535  case mtPig: return 90;
536  case mtPolarBear: return 102;
537  case mtRabbit: return 101;
538  case mtSheep: return 91;
539  case mtShulker: return 69;
540  case mtSilverfish: return 60;
541  case mtSkeleton: return 51;
542  case mtSlime: return 55;
543  case mtSnowGolem: return 97;
544  case mtSpider: return 52;
545  case mtStray: return 6;
546  case mtTraderLlama: return 103;
547  case mtSquid: return 94;
548  case mtVex: return 35;
549  case mtVillager: return 120;
550  case mtVindicator: return 36;
551  case mtWitch: return 66;
552  case mtWither: return 64;
553  case mtWitherSkeleton: return 5;
554  case mtWolf: return 95;
555  case mtZombie: return 54;
556  case mtZombiePigman: return 57;
557  case mtZombieVillager: return 27;
558 
559  default: return 0;
560  }
561 }
562 
563 
564 
565 
566 
568 {
569  return Version::v1_11_0;
570 }
571 
572 
573 
574 
575 
577 {
578  Vector3i Position;
579  if (!a_ByteBuffer.ReadXYZPosition64(Position))
580  {
581  return;
582  }
583 
584  HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Face);
585  HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Hand);
586  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorX);
587  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorY);
588  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorZ);
589 
590  m_Client->HandleRightClick(Position, FaceIntToBlockFace(Face), {FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16)}, Hand == 0);
591 }
592 
593 
594 
595 
596 
597 void cProtocol_1_11_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const
598 {
599  switch (a_BlockEntity.GetBlockType())
600  {
601  case E_BLOCK_BED:
602  {
603  auto & BedEntity = static_cast<const cBedEntity &>(a_BlockEntity);
604  a_Writer.AddInt("color", BedEntity.GetColor()); // New: multicoloured beds
605  break;
606  }
607  case E_BLOCK_MOB_SPAWNER:
608  {
609  auto & MobSpawnerEntity = static_cast<const cMobSpawnerEntity &>(a_BlockEntity);
610  a_Writer.BeginCompound("SpawnData");
611  a_Writer.AddString("id", cMonster::MobTypeToVanillaNBT(MobSpawnerEntity.GetEntity())); // New: uses namespaced ID
612  a_Writer.EndCompound();
613  a_Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay());
614  break;
615  }
616  default: return Super::WriteBlockEntity(a_Writer, a_BlockEntity);
617  }
618 
619  a_Writer.AddInt("x", a_BlockEntity.GetPosX());
620  a_Writer.AddInt("y", a_BlockEntity.GetPosY());
621  a_Writer.AddInt("z", a_BlockEntity.GetPosZ());
622 }
623 
624 
625 
626 
627 
628 void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
629 {
630  using namespace Metadata_1_11;
631 
632  // Common metadata:
633  Int8 Flags = 0;
634  if (a_Entity.IsOnFire())
635  {
636  Flags |= 0x01;
637  }
638  if (a_Entity.IsCrouched())
639  {
640  Flags |= 0x02;
641  }
642  if (a_Entity.IsSprinting())
643  {
644  Flags |= 0x08;
645  }
646  if (a_Entity.IsRclking())
647  {
648  Flags |= 0x10;
649  }
650  if (a_Entity.IsInvisible())
651  {
652  Flags |= 0x20;
653  }
654  a_Pkt.WriteBEUInt8(ENTITY_FLAGS); // Index
655  a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
656  a_Pkt.WriteBEInt8(Flags);
657 
658  switch (a_Entity.GetEntityType())
659  {
660  case cEntity::etPlayer:
661  {
662  auto & Player = static_cast<const cPlayer &>(a_Entity);
663 
664  // TODO Set player custom name to their name.
665  // Then it's possible to move the custom name of mobs to the entities
666  // and to remove the "special" player custom name.
669  a_Pkt.WriteString(Player.GetName());
670 
673  a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
674 
677  a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
678 
681  a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
682  break;
683  }
684  case cEntity::etPickup:
685  {
686  a_Pkt.WriteBEUInt8(ITEM_ITEM);
688  WriteItem(a_Pkt, static_cast<const cPickup &>(a_Entity).GetItem());
689  break;
690  }
691  case cEntity::etMinecart:
692  {
695 
696  // The following expression makes Minecarts shake more with less health or higher damage taken
697  auto & Minecart = static_cast<const cMinecart &>(a_Entity);
698  auto maxHealth = a_Entity.GetMaxHealth();
699  auto curHealth = a_Entity.GetHealth();
700  a_Pkt.WriteVarInt32(static_cast<UInt32>((maxHealth - curHealth) * Minecart.LastDamage() * 4));
701 
702  a_Pkt.WriteBEUInt8(MINECART_SHAKING_DIRECTION); // (doesn't seem to effect anything)
704  a_Pkt.WriteVarInt32(1);
705 
706  a_Pkt.WriteBEUInt8(MINECART_SHAKING_MULTIPLIER); // or damage taken
708  a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10));
709 
710  if (Minecart.GetPayload() == cMinecart::mpNone)
711  {
712  auto & RideableMinecart = static_cast<const cRideableMinecart &>(Minecart);
713  const cItem & MinecartContent = RideableMinecart.GetContent();
714  if (!MinecartContent.IsEmpty())
715  {
718  int Content = MinecartContent.m_ItemType;
719  Content |= MinecartContent.m_ItemDamage << 8;
720  a_Pkt.WriteVarInt32(static_cast<UInt32>(Content));
721 
724  a_Pkt.WriteVarInt32(static_cast<UInt32>(RideableMinecart.GetBlockHeight()));
725 
728  a_Pkt.WriteBool(true);
729  }
730  }
731  else if (Minecart.GetPayload() == cMinecart::mpFurnace)
732  {
735  a_Pkt.WriteBool(static_cast<const cMinecartWithFurnace &>(Minecart).IsFueled());
736  }
737  break;
738  } // case etMinecart
739 
741  {
742  auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
743  switch (Projectile.GetProjectileKind())
744  {
746  {
749  a_Pkt.WriteBEInt8(static_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0);
750  break;
751  }
753  {
754  a_Pkt.WriteBEUInt8(FIREWORK_INFO); // Firework item used for this firework
756  WriteItem(a_Pkt, static_cast<const cFireworkEntity &>(Projectile).GetItem());
757 
758  // FIREWORK_BOOSTED_ENTITY_ID, in 1.11.1 only
759  break;
760  }
762  {
763  a_Pkt.WriteBEUInt8(POTION_THROWN); // Potion item which was thrown
765  WriteItem(a_Pkt, static_cast<const cSplashPotionEntity &>(Projectile).GetItem());
766  }
767  default:
768  {
769  break;
770  }
771  }
772  break;
773  } // case etProjectile
774 
775  case cEntity::etMonster:
776  {
777  WriteMobMetadata(a_Pkt, static_cast<const cMonster &>(a_Entity));
778  break;
779  }
780 
781  case cEntity::etBoat:
782  {
783  auto & Boat = static_cast<const cBoat &>(a_Entity);
784 
787  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetLastDamage()));
788 
791  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetForwardDirection()));
792 
795  a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
796 
797  a_Pkt.WriteBEInt8(BOAT_TYPE);
799  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetMaterial()));
800 
803  a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
804 
807  a_Pkt.WriteBool(Boat.IsLeftPaddleUsed());
808 
809  break;
810  } // case etBoat
811 
813  {
814  auto & Frame = static_cast<const cItemFrame &>(a_Entity);
817  WriteItem(a_Pkt, Frame.GetItem());
820  a_Pkt.WriteVarInt32(Frame.GetItemRotation());
821  break;
822  } // case etItemFrame
823 
825  {
826  const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
827  if (EnderCrystal.DisplaysBeam())
828  {
831  a_Pkt.WriteBool(true); // Dont do a second check if it should display the beam
832  a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
833  }
836  a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
837  break;
838  } // case etEnderCrystal
839 
840  default:
841  {
842  break;
843  }
844  }
845 }
846 
847 
848 
849 
850 
851 void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
852 {
853  using namespace Metadata_1_11;
854 
855  // Living entity Metadata
856  if (a_Mob.HasCustomName())
857  {
858  // TODO: As of 1.9 _all_ entities can have custom names; should this be moved up?
861  a_Pkt.WriteString(a_Mob.GetCustomName());
862 
863  a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME_VISIBLE); // Custom name always visible
865  a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible());
866  }
867 
870  a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));
871 
872  switch (a_Mob.GetMobType())
873  {
874  case mtBat:
875  {
876  auto & Bat = static_cast<const cBat &>(a_Mob);
877  a_Pkt.WriteBEUInt8(BAT_HANGING);
879  a_Pkt.WriteBEInt8(Bat.IsHanging() ? 1 : 0);
880  break;
881  } // case mtBat
882 
883  case mtChicken:
884  {
885  auto & Chicken = static_cast<const cChicken &>(a_Mob);
886 
887  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
889  a_Pkt.WriteBool(Chicken.IsBaby());
890  break;
891  } // case mtChicken
892 
893  case mtCow:
894  {
895  auto & Cow = static_cast<const cCow &>(a_Mob);
896 
897  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
899  a_Pkt.WriteBool(Cow.IsBaby());
900  break;
901  } // case mtCow
902 
903  case mtCreeper:
904  {
905  auto & Creeper = static_cast<const cCreeper &>(a_Mob);
906  a_Pkt.WriteBEUInt8(CREEPER_STATE); // (idle or "blowing")
908  a_Pkt.WriteVarInt32(Creeper.IsBlowing() ? 1 : static_cast<UInt32>(-1));
909 
912  a_Pkt.WriteBool(Creeper.IsCharged());
913 
916  a_Pkt.WriteBool(Creeper.IsBurnedWithFlintAndSteel());
917  break;
918  } // case mtCreeper
919 
920  case mtEnderman:
921  {
922  auto & Enderman = static_cast<const cEnderman &>(a_Mob);
925  UInt32 Carried = 0;
926  Carried |= static_cast<UInt32>(Enderman.GetCarriedBlock() << 4);
927  Carried |= Enderman.GetCarriedMeta();
928  a_Pkt.WriteVarInt32(Carried);
929 
932  a_Pkt.WriteBool(Enderman.IsScreaming());
933  break;
934  } // case mtEnderman
935 
936  case mtGhast:
937  {
938  auto & Ghast = static_cast<const cGhast &>(a_Mob);
941  a_Pkt.WriteBool(Ghast.IsCharging());
942  break;
943  } // case mtGhast
944 
945  case mtHorse:
946  {
947  // XXX This behaves incorrectly with different variants; horses have different entity IDs now
948 
949  // Abstract horse
950  auto & Horse = static_cast<const cHorse &>(a_Mob);
951  Int8 Flags = 0;
952  if (Horse.IsTame())
953  {
954  Flags |= 0x02;
955  }
956  if (Horse.IsSaddled())
957  {
958  Flags |= 0x04;
959  }
960  if (Horse.IsChested())
961  {
962  Flags |= 0x08;
963  }
964  if (Horse.IsEating())
965  {
966  Flags |= 0x20;
967  }
968  if (Horse.IsRearing())
969  {
970  Flags |= 0x40;
971  }
972  if (Horse.IsMthOpen())
973  {
974  Flags |= 0x80;
975  }
978  a_Pkt.WriteBEInt8(Flags);
979 
980  // This doesn't exist any more; it'll cause horses to all be the normal type
981  // a_Pkt.WriteBEUInt8(HORSE_TYPE);
982  // a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
983  // a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseType()));
984 
985  // Regular horses
986  a_Pkt.WriteBEUInt8(HORSE_VARIANT); // Color / style
988  int Appearance = 0;
989  Appearance = Horse.GetHorseColor();
990  Appearance |= Horse.GetHorseStyle() << 8;
991  a_Pkt.WriteVarInt32(static_cast<UInt32>(Appearance));
992 
993  a_Pkt.WriteBEUInt8(HORSE_ARMOR);
995  a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseArmour()));
996 
997  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
999  a_Pkt.WriteBool(Horse.IsBaby());
1000  break;
1001  } // case mtHorse
1002 
1003  case mtMagmaCube:
1004  {
1005  auto & MagmaCube = static_cast<const cMagmaCube &>(a_Mob);
1006  a_Pkt.WriteBEUInt8(SLIME_SIZE);
1008  a_Pkt.WriteVarInt32(static_cast<UInt32>(MagmaCube.GetSize()));
1009  break;
1010  } // case mtMagmaCube
1011 
1012  case mtOcelot:
1013  {
1014  // Todo: move unnecessary to cat
1015  auto & Ocelot = static_cast<const cOcelot &>(a_Mob);
1016 
1017  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1019  a_Pkt.WriteBool(Ocelot.IsBaby());
1020 
1021  Int8 OcelotStatus = 0;
1022  if (Ocelot.IsSitting())
1023  {
1024  OcelotStatus |= 0x1;
1025  }
1026  if (Ocelot.IsTame())
1027  {
1028  OcelotStatus |= 0x4;
1029  }
1032  a_Pkt.WriteBEInt8(OcelotStatus);
1033 
1034  a_Pkt.WriteBEUInt8(OCELOT_TYPE);
1036  a_Pkt.WriteVarInt32(static_cast<UInt32>(Ocelot.GetOcelotType()));
1037 
1038  break;
1039  } // case mtOcelot
1040 
1041  case mtPig:
1042  {
1043  auto & Pig = static_cast<const cPig &>(a_Mob);
1044 
1045  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1047  a_Pkt.WriteBool(Pig.IsBaby());
1048 
1051  a_Pkt.WriteBool(Pig.IsSaddled());
1052 
1053  // PIG_TOTAL_CARROT_ON_A_STICK_BOOST in 1.11.1 only
1054  break;
1055  } // case mtPig
1056 
1057  case mtRabbit:
1058  {
1059  auto & Rabbit = static_cast<const cRabbit &>(a_Mob);
1060  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1062  a_Pkt.WriteBool(Rabbit.IsBaby());
1063 
1064  a_Pkt.WriteBEUInt8(RABBIT_TYPE);
1066  a_Pkt.WriteVarInt32(static_cast<UInt32>(Rabbit.GetRabbitType()));
1067  break;
1068  } // case mtRabbit
1069 
1070  case mtSheep:
1071  {
1072  auto & Sheep = static_cast<const cSheep &>(a_Mob);
1073 
1074  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1076  a_Pkt.WriteBool(Sheep.IsBaby());
1077 
1078  a_Pkt.WriteBEUInt8(SHEEP_STATUS);
1080  Int8 SheepMetadata = 0;
1081  SheepMetadata = static_cast<Int8>(Sheep.GetFurColor());
1082  if (Sheep.IsSheared())
1083  {
1084  SheepMetadata |= 0x10;
1085  }
1086  a_Pkt.WriteBEInt8(SheepMetadata);
1087  break;
1088  } // case mtSheep
1089 
1090  case mtSkeleton:
1091  {
1092  auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
1095  a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
1096 
1099  a_Pkt.WriteBool(Skeleton.IsChargingBow());
1100  break;
1101  } // case mtSkeleton
1102 
1103  case mtSlime:
1104  {
1105  auto & Slime = static_cast<const cSlime &>(a_Mob);
1106  a_Pkt.WriteBEUInt8(SLIME_SIZE);
1108  a_Pkt.WriteVarInt32(static_cast<UInt32>(Slime.GetSize()));
1109  break;
1110  } // case mtSlime
1111 
1112  case mtVillager:
1113  {
1114  auto & Villager = static_cast<const cVillager &>(a_Mob);
1115  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1117  a_Pkt.WriteBool(Villager.IsBaby());
1118 
1121  a_Pkt.WriteVarInt32(static_cast<UInt32>(Villager.GetVilType()));
1122  break;
1123  } // case mtVillager
1124 
1125  case mtWitch:
1126  {
1127  auto & Witch = static_cast<const cWitch &>(a_Mob);
1130  a_Pkt.WriteBool(Witch.IsAngry());
1131  break;
1132  } // case mtWitch
1133 
1134  case mtWither:
1135  {
1136  auto & Wither = static_cast<const cWither &>(a_Mob);
1139  a_Pkt.WriteVarInt32(Wither.GetWitherInvulnerableTicks());
1140 
1141  // TODO: Use boss bar packet for health
1142  break;
1143  } // case mtWither
1144 
1145  case mtWolf:
1146  {
1147  auto & Wolf = static_cast<const cWolf &>(a_Mob);
1148  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1150  a_Pkt.WriteBool(Wolf.IsBaby());
1151 
1152  Int8 WolfStatus = 0;
1153  if (Wolf.IsSitting())
1154  {
1155  WolfStatus |= 0x1;
1156  }
1157  if (Wolf.IsAngry())
1158  {
1159  WolfStatus |= 0x2;
1160  }
1161  if (Wolf.IsTame())
1162  {
1163  WolfStatus |= 0x4;
1164  }
1167  a_Pkt.WriteBEInt8(WolfStatus);
1168 
1171  a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); // TODO Not use the current health
1172 
1173  a_Pkt.WriteBEUInt8(WOLF_BEGGING);
1175  a_Pkt.WriteBool(Wolf.IsBegging());
1176 
1179  a_Pkt.WriteVarInt32(static_cast<UInt32>(Wolf.GetCollarColor()));
1180  break;
1181  } // case mtWolf
1182 
1183  case mtZombie:
1184  {
1185  // XXX Zombies were also split into new subclasses; this doesn't handle that.
1186  auto & Zombie = static_cast<const cZombie &>(a_Mob);
1189  a_Pkt.WriteBool(Zombie.IsBaby());
1190  break;
1191  } // case mtZombie
1192 
1193  case mtZombiePigman:
1194  {
1195  auto & ZombiePigman = static_cast<const cZombiePigman &>(a_Mob);
1196  a_Pkt.WriteBEUInt8(AGEABLE_BABY);
1198  a_Pkt.WriteBool(ZombiePigman.IsBaby());
1199  break;
1200  } // case mtZombiePigman
1201 
1202  case mtZombieVillager:
1203  {
1204  auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
1207  a_Pkt.WriteBool(ZombieVillager.IsBaby());
1208 
1211  a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.ConversionTime()));
1212 
1215  a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.GetProfession()));
1216  break;
1217  } // case mtZombieVillager
1218 
1219  case mtBlaze:
1220  case mtElderGuardian:
1221  case mtGuardian:
1222  case mtSnowGolem:
1223  {
1224  // TODO: Mobs with extra fields that aren't implemented
1225  break;
1226  }
1227 
1228  case mtCat:
1229 
1230  case mtDonkey:
1231  case mtMule:
1232 
1233  case mtEvoker:
1234 
1235  case mtLlama:
1236 
1237  case mtPolarBear:
1238 
1239  case mtShulker:
1240 
1241  case mtSkeletonHorse:
1242  case mtZombieHorse:
1243 
1244  case mtVex:
1245 
1246  case mtVindicator:
1247  {
1248  // Todo: Mobs not added yet. Grouped ones have the same metadata
1249  ASSERT(!"cProtocol_1_11::WriteMobMetadata: received unimplemented type");
1250  break;
1251  }
1252 
1253  case mtCaveSpider:
1254  case mtEnderDragon:
1255  case mtEndermite:
1256  case mtGiant:
1257  case mtIronGolem:
1258  case mtMooshroom:
1259  case mtSilverfish:
1260  case mtStray:
1261  case mtSpider:
1262  case mtSquid:
1263  case mtWitherSkeleton:
1264  {
1265  // Mobs without additional metadata
1266  break;
1267  }
1268 
1269  default: UNREACHABLE("cProtocol_1_11::WriteMobMetadata: received mob of invalid type");
1270  } // switch (a_Mob.GetType())
1271 }
1272 
1273 
1274 
1275 
1276 
1278 // cProtocol_1_11_1:
1279 
1281 {
1282  return Version::v1_11_1;
1283 }
@ E_BLOCK_HEAD
Definition: BlockType.h:159
@ E_BLOCK_STANDING_BANNER
Definition: BlockType.h:195
@ E_BLOCK_ENCHANTMENT_TABLE
Definition: BlockType.h:131
@ E_BLOCK_BEACON
Definition: BlockType.h:153
@ E_BLOCK_CHEST
Definition: BlockType.h:64
@ E_BLOCK_TRAPPED_CHEST
Definition: BlockType.h:161
@ E_BLOCK_COMMAND_BLOCK
Definition: BlockType.h:152
@ E_BLOCK_BED
Definition: BlockType.h:36
@ E_BLOCK_END_PORTAL
Definition: BlockType.h:134
@ E_BLOCK_FLOWER_POT
Definition: BlockType.h:155
@ E_BLOCK_MOB_SPAWNER
Definition: BlockType.h:62
@ E_BLOCK_WALL_BANNER
Definition: BlockType.h:196
EntityAnimation
Definition: Defines.h:458
#define UNREACHABLE(x)
Definition: Globals.h:288
unsigned int UInt32
Definition: Globals.h:157
signed short Int16
Definition: Globals.h:153
signed char Int8
Definition: Globals.h:154
signed int Int32
Definition: Globals.h:152
unsigned char UInt8
Definition: Globals.h:159
#define ASSERT(x)
Definition: Globals.h:276
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:347
unsigned char Byte
Definition: Globals.h:161
eMonsterType
Identifies individual monster type.
Definition: MonsterTypes.h:11
@ mtZombieVillager
Definition: MonsterTypes.h:82
@ mtVindicator
Definition: MonsterTypes.h:72
@ mtElderGuardian
Definition: MonsterTypes.h:25
@ mtSkeleton
Definition: MonsterTypes.h:59
@ mtSheep
Definition: MonsterTypes.h:56
@ mtEndermite
Definition: MonsterTypes.h:28
@ mtPolarBear
Definition: MonsterTypes.h:51
@ mtMagmaCube
Definition: MonsterTypes.h:40
@ mtWolf
Definition: MonsterTypes.h:77
@ mtStray
Definition: MonsterTypes.h:65
@ mtRabbit
Definition: MonsterTypes.h:53
@ mtTraderLlama
Definition: MonsterTypes.h:67
@ mtCat
Definition: MonsterTypes.h:16
@ mtZombie
Definition: MonsterTypes.h:79
@ mtOcelot
Definition: MonsterTypes.h:43
@ mtDonkey
Definition: MonsterTypes.h:23
@ mtVex
Definition: MonsterTypes.h:70
@ mtEnderman
Definition: MonsterTypes.h:27
@ mtHusk
Definition: MonsterTypes.h:36
@ mtCaveSpider
Definition: MonsterTypes.h:17
@ mtEvoker
Definition: MonsterTypes.h:29
@ mtShulker
Definition: MonsterTypes.h:57
@ mtWither
Definition: MonsterTypes.h:75
@ mtSkeletonHorse
Definition: MonsterTypes.h:60
@ mtPig
Definition: MonsterTypes.h:47
@ mtVillager
Definition: MonsterTypes.h:71
@ mtHorse
Definition: MonsterTypes.h:34
@ mtZombieHorse
Definition: MonsterTypes.h:80
@ mtWitch
Definition: MonsterTypes.h:74
@ mtCow
Definition: MonsterTypes.h:20
@ mtEnderDragon
Definition: MonsterTypes.h:26
@ mtMooshroom
Definition: MonsterTypes.h:41
@ mtSquid
Definition: MonsterTypes.h:64
@ mtInvalidType
Definition: MonsterTypes.h:12
@ mtBat
Definition: MonsterTypes.h:14
@ mtChicken
Definition: MonsterTypes.h:18
@ mtGiant
Definition: MonsterTypes.h:32
@ mtSnowGolem
Definition: MonsterTypes.h:62
@ mtBlaze
Definition: MonsterTypes.h:15
@ mtLlama
Definition: MonsterTypes.h:39
@ mtIronGolem
Definition: MonsterTypes.h:38
@ mtCreeper
Definition: MonsterTypes.h:21
@ mtSpider
Definition: MonsterTypes.h:63
@ mtMule
Definition: MonsterTypes.h:42
@ mtGhast
Definition: MonsterTypes.h:31
@ mtSilverfish
Definition: MonsterTypes.h:58
@ mtZombiePigman
Definition: MonsterTypes.h:85
@ mtSlime
Definition: MonsterTypes.h:61
@ mtWitherSkeleton
Definition: MonsterTypes.h:76
@ mtGuardian
Definition: MonsterTypes.h:33
#define HANDLE_READ(ByteBuf, Proc, Type, Var)
Macros used to read packets more easily.
Definition: Packetizer.h:28
@ Rabbit
@ Chicken
@ Minecart
@ MINECART_COMMAND_BLOCK_LAST_OUTPUT
@ AREA_EFFECT_CLOUD_SINGLE_POINT_EFFECT
@ ARMOR_STAND_RIGHT_LEG_ROTATION
@ ABSTRACT_SKELETON_ARMS_SWINGING
@ AREA_EFFECT_CLOUD_PARTICLE_PARAMETER1
@ PIG_TOTAL_CARROT_ON_A_STICK_BOOST
@ AREA_EFFECT_CLOUD_PARTICLE_PARAMETER2
@ MINECART_COMMAND_BLOCK_COMMAND
@ AREA_EFFECT_CLOUD_PARTICLE_ID
@ ARMOR_STAND_RIGHT_ARM_ROTATION
@ SHULKER_ATTACHMENT_FALLING_BLOCK_POSITION
int GetPosZ() const
Definition: BlockEntity.h:93
int GetPosY() const
Definition: BlockEntity.h:92
int GetPosX() const
Definition: BlockEntity.h:91
BLOCKTYPE GetBlockType() const
Definition: BlockEntity.h:97
An object that can store incoming bytes and lets its clients read the bytes sequentially The bytes ar...
Definition: ByteBuffer.h:32
bool ReadXYZPosition64(int &a_BlockX, int &a_BlockY, int &a_BlockZ)
Definition: ByteBuffer.cpp:505
void HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_Cursor, bool a_UsedMainHand)
bool IsCritical(void) const
Returns true if the arrow is set as critical.
Definition: ArrowEntity.h:70
Definition: Boat.h:20
Definition: Entity.h:76
virtual bool IsRclking(void) const
Definition: Entity.h:490
double GetSpeedZ(void) const
Definition: Entity.h:204
virtual bool IsCrouched(void) const
Definition: Entity.h:486
float GetMaxHealth(void) const
Definition: Entity.h:407
double GetSpeedY(void) const
Definition: Entity.h:203
Vector3d GetLastSentPosition(void) const
Returns the last position we sent to all the clients.
Definition: Entity.h:304
UInt32 GetUniqueID(void) const
Definition: Entity.h:253
eEntityType GetEntityType(void) const
Definition: Entity.h:156
double GetPitch(void) const
Definition: Entity.h:199
virtual bool IsOnFire(void) const
Definition: Entity.h:489
double GetHeadYaw(void) const
Definition: Entity.h:192
virtual bool IsInvisible(void) const
Definition: Entity.h:488
double GetYaw(void) const
Definition: Entity.h:198
float GetHealth(void) const
Returns the health of this entity.
Definition: Entity.h:367
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:297
@ etPickup
Definition: Entity.h:93
@ etProjectile
Definition: Entity.h:99
@ etItemFrame
Definition: Entity.h:102
@ etMinecart
Definition: Entity.h:96
@ etEnderCrystal
Definition: Entity.h:91
@ etMonster
Definition: Entity.h:94
@ etBoat
Definition: Entity.h:97
@ etPlayer
Definition: Entity.h:92
virtual bool IsSprinting(void) const
Definition: Entity.h:492
double GetSpeedX(void) const
Definition: Entity.h:202
@ mpNone
Definition: Minecart.h:31
@ mpFurnace
Definition: Minecart.h:33
bool IsFueled(void) const
Definition: Minecart.h:201
Definition: Pickup.h:20
Definition: Player.h:29
Definition: Item.h:37
bool IsEmpty(void) const
Returns true if the item represents an empty stack - either the type is invalid, or count is zero.
Definition: Item.h:69
short m_ItemType
Definition: Item.h:163
short m_ItemDamage
Definition: Item.h:165
Definition: Bat.h:12
Definition: Cow.h:12
Definition: Ghast.h:12
Definition: Horse.h:14
bool HasCustomName(void) const
Returns true if the monster has a custom name.
Definition: Monster.h:165
const AString & GetCustomName(void) const
Gets the custom name of the monster.
Definition: Monster.h:168
bool IsCustomNameAlwaysVisible(void) const
Is the custom name of this monster always visible? If not, you only see the name when you sight the m...
Definition: Monster.h:175
eMonsterType GetMobType(void) const
Definition: Monster.h:70
static AString MobTypeToVanillaNBT(eMonsterType a_MobType)
Translates the MobType enum to the vanilla nbt name.
Definition: Monster.cpp:1044
Definition: Ocelot.h:13
Definition: Pig.h:12
Definition: Rabbit.h:27
Definition: Sheep.h:12
Definition: Slime.h:12
Definition: Witch.h:12
Definition: Wither.h:12
Definition: Wolf.h:14
Definition: Zombie.h:11
Composes an individual packet in the protocol's m_OutPacketBuffer; sends it just before being destruc...
Definition: Packetizer.h:60
void WriteVarInt32(UInt32 a_Value)
Definition: Packetizer.h:141
void WriteBEInt32(Int32 a_Value)
Definition: Packetizer.h:105
void WriteBool(bool a_Value)
Definition: Packetizer.h:76
void WriteXYZPosition64(int a_BlockX, int a_BlockY, int a_BlockZ)
Writes the specified block position as a single encoded 64-bit BigEndian integer.
Definition: Packetizer.h:161
void WriteBEUInt64(UInt64 a_Value)
Definition: Packetizer.h:123
void WriteBEFloat(float a_Value)
Definition: Packetizer.h:129
void WriteBEInt16(Int16 a_Value)
Definition: Packetizer.h:93
void WriteString(const AString &a_Value)
Definition: Packetizer.h:147
void WriteBEUInt8(UInt8 a_Value)
Definition: Packetizer.h:81
void WriteBEDouble(double a_Value)
Definition: Packetizer.h:135
void WriteBuf(const ContiguousByteBufferView a_Data)
Definition: Packetizer.h:153
void WriteByteAngle(double a_Angle)
Writes the specified angle using a single byte.
Definition: Packetizer.cpp:26
void WriteBEInt8(Int8 a_Value)
Definition: Packetizer.h:87
@ pktUpdateBlockEntity
Definition: Protocol.h:125
@ pktCollectEntity
Definition: Protocol.h:66
@ pktSpawnMob
Definition: Protocol.h:112
@ pktTitle
Definition: Protocol.h:122
Version
The protocol version number, received from the client in the Handshake packet.
Definition: Protocol.h:335
cClientHandle * m_Client
Definition: Protocol.h:472
virtual void SendSoundEffect(const AString &a_SoundName, Vector3d a_Origin, float a_Volume, float a_Pitch) override
virtual void WriteMobMetadata(cPacketizer &a_Pkt, const cMonster &a_Mob) const override
Writes the mob-specific metadata for the specified mob.
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual void SendResetTitle(void) override
virtual void WriteBlockEntity(cFastNBTWriter &a_Writer, const cBlockEntity &a_BlockEntity) const override
Writes the block entity data for the specified block entity into the packet.
virtual void SendEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation) override
virtual void SendCollectEntity(const cEntity &a_Collected, const cEntity &a_Collector, unsigned a_Count) override
virtual void WriteEntityMetadata(cPacketizer &a_Pkt, const cEntity &a_Entity) const override
Writes the metadata for the specified entity, not including the terminating 0x7f.
virtual void SendSpawnMob(const cMonster &a_Mob) override
virtual void SendHideTitle(void) override
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override
Converts an animation into an ID suitable for use with the Entity Status packet.
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override
Converts eMonsterType to protocol-specific mob types.
virtual void HandlePacketBlockPlace(cByteBuffer &a_ByteBuffer) override
virtual void SendUpdateBlockEntity(cBlockEntity &a_BlockEntity) override
virtual void SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override
virtual Version GetProtocolVersion() const override
Returns the protocol version.
State m_State
State of the protocol.
Definition: Protocol_1_8.h:143
static eBlockFace FaceIntToBlockFace(Int32 a_FaceInt)
Converts the BlockFace received by the protocol into eBlockFace constants.
virtual void SendEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation) override
virtual void WriteItem(cPacketizer &a_Pkt, const cItem &a_Item) const override
Writes the item data into a packet.
virtual void WriteBlockEntity(cFastNBTWriter &a_Writer, const cBlockEntity &a_BlockEntity) const override
Writes the block entity data for the specified block entity into the packet.
virtual void SendEntityPosition(const cEntity &a_Entity) override
@ METADATA_TYPE_OPTIONAL_POSITION
Definition: Protocol_1_9.h:116
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override
Converts an animation into an ID suitable for use with the Entity Status packet.
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
void AddShort(const AString &a_Name, Int16 a_Value)
Definition: FastNBT.cpp:561
void AddInt(const AString &a_Name, Int32 a_Value)
Definition: FastNBT.cpp:572
void Finish(void)
Definition: FastNBT.cpp:674
void AddString(const AString &a_Name, std::string_view a_Value)
Definition: FastNBT.cpp:616
void EndCompound(void)
Definition: FastNBT.cpp:499
void BeginCompound(const AString &a_Name)
Definition: FastNBT.cpp:481
ContiguousByteBufferView GetResult(void) const
Definition: FastNBT.h:351