Cuberite
A lightweight, fast and extensible game server for Minecraft
Protocol_1_14.cpp
Go to the documentation of this file.
1 
2 // Protocol_1_14.cpp
3 
4 /*
5 Implements the 1.14 protocol classes:
6 - release 1.14 protocol (#477)
7 */
8 
9 #include "Globals.h"
10 #include "Protocol_1_14.h"
11 #include "Packetizer.h"
12 #include "JsonUtils.h"
13 #include "../Root.h"
14 #include "../Server.h"
15 #include "../World.h"
16 #include "../UI/HorseWindow.h"
17 #include "../ClientHandle.h"
18 #include "../WorldStorage/FastNBT.h"
19 #include "../BlockEntities/BlockEntity.h"
20 
21 #include "../Entities/ArrowEntity.h"
22 #include "../Entities/ItemFrame.h"
23 #include "../Mobs/Bat.h"
24 #include "../Entities/Boat.h"
25 #include "../Mobs/Chicken.h"
26 #include "../Mobs/Cow.h"
27 #include "../Mobs/Creeper.h"
28 #include "../Entities/EnderCrystal.h"
29 #include "../Mobs/Enderman.h"
30 #include "../Mobs/Ghast.h"
31 #include "../Mobs/Horse.h"
32 #include "../Mobs/MagmaCube.h"
33 #include "../Entities/Minecart.h"
34 #include "../Mobs/Ocelot.h"
35 #include "../Entities/Pickup.h"
36 #include "../Mobs/Pig.h"
37 #include "../Entities/Player.h"
38 #include "../Mobs/Rabbit.h"
39 #include "../Mobs/Sheep.h"
40 #include "../Mobs/Skeleton.h"
41 #include "../Mobs/Slime.h"
42 #include "../Mobs/Villager.h"
43 #include "../Mobs/Wolf.h"
44 #include "../Mobs/Wither.h"
45 #include "../Mobs/Zombie.h"
46 #include "../Mobs/ZombiePigman.h"
47 
48 #include "Palettes/Upgrade.h"
49 #include "Palettes/Palette_1_14.h"
50 
51 
52 
53 
54 
56 // cProtocol_1_14:
57 
58 void cProtocol_1_14::SendBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType)
59 {
60  ASSERT(m_State == 3); // In game mode?
61 
62  cPacketizer Pkt(*this, pktBlockAction);
63  Pkt.WriteXZYPosition64(a_BlockPos);
64  Pkt.WriteBEInt8(a_Byte1);
65  Pkt.WriteBEInt8(a_Byte2);
66  Pkt.WriteVarInt32(a_BlockType);
67 }
68 
69 
70 
71 
72 
73 void cProtocol_1_14::SendBlockBreakAnim(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage)
74 {
75  ASSERT(m_State == 3); // In game mode?
76 
77  cPacketizer Pkt(*this, pktBlockBreakAnim);
78  Pkt.WriteVarInt32(a_EntityID);
79  Pkt.WriteXZYPosition64(a_BlockPos);
80  Pkt.WriteBEInt8(a_Stage);
81 }
82 
83 
84 
85 
86 
87 void cProtocol_1_14::SendBlockChange(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
88 {
89  cPacketizer Pkt(*this, pktBlockChange);
90  Pkt.WriteXZYPosition64(a_BlockPos);
91  Pkt.WriteVarInt32(GetProtocolBlockType(a_BlockType, a_BlockMeta));
92 }
93 
94 
95 
96 
97 
99 {
100 }
101 
102 
103 
104 
105 
107 {
108  if (a_Animation == EntityAnimation::PlayerEntersBed)
109  {
110  // Use Bed packet removed, through metadata instead:
111  SendEntityMetadata(a_Entity);
112  return;
113  }
114 
115  Super::SendEntityAnimation(a_Entity, a_Animation);
116 }
117 
118 
119 
120 
121 
122 void cProtocol_1_14::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
123 {
124  ASSERT(m_State == 3); // In game mode?
125 
126  cPacketizer Pkt(*this, pktSpawnObject);
127  Pkt.WriteVarInt32(a_Entity.GetUniqueID());
128 
129  // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
130  Pkt.WriteBEUInt64(0);
131  Pkt.WriteBEUInt64(a_Entity.GetUniqueID());
132 
133  Pkt.WriteVarInt32(a_ObjectType);
134  Pkt.WriteBEDouble(a_Entity.GetPosX());
135  Pkt.WriteBEDouble(a_Entity.GetPosY());
136  Pkt.WriteBEDouble(a_Entity.GetPosZ());
137  Pkt.WriteByteAngle(a_Entity.GetPitch());
138  Pkt.WriteByteAngle(a_Entity.GetYaw());
139  Pkt.WriteBEInt32(a_ObjectData);
140  Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
141  Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
142  Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
143 }
144 
145 
146 
147 
148 
149 void cProtocol_1_14::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
150 {
151  // Send the Join Game packet:
152  {
153  cServer * Server = cRoot::Get()->GetServer();
154  cPacketizer Pkt(*this, pktJoinGame);
155  Pkt.WriteBEUInt32(a_Player.GetUniqueID());
156  Pkt.WriteBEUInt8(static_cast<UInt8>(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0));
157  Pkt.WriteBEInt32(static_cast<Int32>(a_World.GetDimension()));
158  Pkt.WriteBEUInt8(static_cast<UInt8>(Clamp<size_t>(Server->GetMaxPlayers(), 0, 255)));
159  Pkt.WriteString("default");
161  Pkt.WriteBool(false);
162  }
163 
164  // Send the spawn position:
165  {
166  cPacketizer Pkt(*this, pktSpawnPosition);
167  Pkt.WriteXZYPosition64(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
168  }
169 
170  // Send the server difficulty:
171  {
172  cPacketizer Pkt(*this, pktDifficulty);
173  Pkt.WriteBEInt8(1);
174  Pkt.WriteBool(false); // Difficulty locked?
175  }
176 }
177 
178 
179 
180 
181 
182 void cProtocol_1_14::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataStartY)
183 {
184 }
185 
186 
187 
188 
189 
191 {
192 }
193 
194 
195 
196 
197 
198 void cProtocol_1_14::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data)
199 {
200  ASSERT(m_State == 3); // In game mode?
201 
202  const auto ParticleID = GetProtocolParticleID(a_ParticleName);
203 
204  cPacketizer Pkt(*this, pktParticleEffect);
205  Pkt.WriteBEInt32(ParticleID);
206  Pkt.WriteBool(false);
207  Pkt.WriteBEFloat(a_Src.x);
208  Pkt.WriteBEFloat(a_Src.y);
209  Pkt.WriteBEFloat(a_Src.z);
210  Pkt.WriteBEFloat(a_Offset.x);
211  Pkt.WriteBEFloat(a_Offset.y);
212  Pkt.WriteBEFloat(a_Offset.z);
213  Pkt.WriteBEFloat(a_ParticleData);
214  Pkt.WriteBEInt32(a_ParticleAmount);
215 
216  switch (ParticleID)
217  {
218  // blockdust
219  case 3:
220  {
221  Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0]));
222  break;
223  }
224  }
225 }
226 
227 
228 
229 
230 
232 {
233  cPacketizer Pkt(*this, pktRespawn);
234  cPlayer * Player = m_Client->GetPlayer();
235  Pkt.WriteBEInt32(static_cast<Int32>(a_Dimension));
236  Pkt.WriteBEUInt8(static_cast<Byte>(Player->GetEffectiveGameMode()));
237  Pkt.WriteString("default");
238 }
239 
240 
241 
242 
243 
244 void cProtocol_1_14::SendSoundParticleEffect(const EffectID a_EffectID, Vector3i a_Origin, int a_Data)
245 {
246  ASSERT(m_State == 3); // In game mode?
247 
248  // Note: Particles from block break missing
249 
251  Pkt.WriteBEInt32(static_cast<int>(a_EffectID));
252  Pkt.WriteXYZPosition64(a_Origin);
253  Pkt.WriteBEInt32(a_Data);
254  Pkt.WriteBool(false);
255 }
256 
257 
258 
259 
260 
262 {
263  ASSERT(m_State == 3); // In game mode?
264 
265  Byte Action;
266  switch (a_BlockEntity.GetBlockType())
267  {
268  case E_BLOCK_CHEST:
270  case E_BLOCK_END_PORTAL:
272  {
273  // The ones with a action of 0 is just a workaround to send the block entities to a client.
274  // Todo: 18.09.2020 - remove this when block entities are transmitted in the ChunkData packet - 12xx12
275  Action = 0;
276  break;
277  }
278 
279  case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
280  case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
281  case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity
282  case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
283  // case E_BLOCK_CONDUIT: Action = 5; break; // Update Conduit entity
285  case E_BLOCK_WALL_BANNER: Action = 6; break; // Update banner entity
286  // case Structure Block: Action = 7; break; // Update Structure tile entity
287  case E_BLOCK_END_GATEWAY: Action = 8; break; // Update destination for a end gateway entity
288  case E_BLOCK_SIGN_POST: Action = 9; break; // Update sign entity
289  // case E_BLOCK_SHULKER_BOX: Action = 10; break; // sets shulker box - not used just here if anyone is confused from reading the protocol wiki
290  case E_BLOCK_BED: Action = 11; break; // Update bed color
291  // case E_BLOCK_JIGSAW: Action = 12; break;
292  // case E_BLOCK_CAMPFIRE: Action = 13; break;
293 
294  default: return; // Block entities change between versions
295  }
296 
297  cPacketizer Pkt(*this, pktUpdateBlockEntity);
298  Pkt.WriteXZYPosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ());
299  Pkt.WriteBEUInt8(Action);
300 
301  cFastNBTWriter Writer;
302  WriteBlockEntity(Writer, a_BlockEntity);
303  Writer.Finish();
304  Pkt.WriteBuf(Writer.GetResult());
305 }
306 
307 
308 
309 
310 
311 void cProtocol_1_14::SendUpdateSign(Vector3i a_BlockPos, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
312 {
313 }
314 
315 
316 
317 
318 
320 {
321  ASSERT(m_State == 3); // In game mode?
322 
323  if (a_Window.GetWindowType() < 0)
324  {
325  // Do not send this packet for player inventory windows
326  return;
327  }
328 
329  if (a_Window.GetWindowType() == cWindow::wtAnimalChest)
330  {
331  cPacketizer Pkt(*this, pktHorseWindowOpen);
332  Pkt.WriteBEUInt8(static_cast<UInt8>(a_Window.GetWindowID()));
333  Pkt.WriteVarInt32(static_cast<UInt32>(a_Window.GetNumSlots()));
334 
335  UInt32 HorseID = static_cast<const cHorseWindow &>(a_Window).GetHorseID();
336  Pkt.WriteBEInt32(static_cast<Int32>(HorseID));
337  }
338  else
339  {
340  cPacketizer Pkt(*this, pktWindowOpen);
341  Pkt.WriteVarInt32(static_cast<UInt8>(a_Window.GetWindowID()));
342 
343  switch (a_Window.GetWindowType())
344  {
345  case cWindow::wtChest:
346  {
347  // Chests can have multiple size
348  Pkt.WriteVarInt32(static_cast<UInt32>(a_Window.GetNumNonInventorySlots() / 9 - 1));
349  break;
350  }
351  case cWindow::wtDropper:
353  {
354  Pkt.WriteVarInt32(6);
355  break;
356  }
357  case cWindow::wtAnvil:
358  {
359  Pkt.WriteVarInt32(7);
360  break;
361  }
362  case cWindow::wtBeacon:
363  {
364  Pkt.WriteVarInt32(8);
365  break;
366  }
367  case cWindow::wtBrewery:
368  {
369  Pkt.WriteVarInt32(10);
370  break;
371  }
373  {
374  Pkt.WriteVarInt32(11);
375  break;
376  }
378  {
379  Pkt.WriteVarInt32(12);
380  break;
381  }
382  case cWindow::wtFurnace:
383  {
384  Pkt.WriteVarInt32(13);
385  break;
386  }
387  /*
388  case cWindow::wtGrindstone:
389  {
390  Pkt.WriteVarInt32(14);
391  break;
392  }
393  */
394  case cWindow::wtHopper:
395  {
396  Pkt.WriteVarInt32(15);
397  break;
398  }
399  /*
400  case cWindow::wtLectern:
401  {
402  Pkt.WriteVarInt32(16);
403  break;
404  }
405  case cWindow::wtLoom:
406  {
407  Pkt.WriteVarInt32(17);
408  break;
409  }
410  */
411  case cWindow::wtNPCTrade:
412  {
413  Pkt.WriteVarInt32(18);
414  break;
415  }
416  /*
417  case cWindow::wtShulker:
418  {
419  Pkt.WriteVarInt32(19);
420  break;
421  }
422  case cWindow::wtSmoker:
423  {
424  Pkt.WriteVarInt32(20);
425  break;
426  }
427  case cWindow::wtCartography:
428  {
429  Pkt.WriteVarInt32(21);
430  break;
431  }
432  case cWindow::wtStonecutter:
433  {
434  Pkt.WriteVarInt32(22);
435  break;
436  }
437  */
438  default:
439  {
440  Pkt.WriteBEUInt8(static_cast<UInt8>(a_Window.GetNumNonInventorySlots()));
441  break;
442  }
443  }
444 
446  }
447 }
448 
449 
450 
451 
452 
454 {
455  switch (a_PacketType)
456  {
457  case cProtocol::pktAttachEntity: return 0x4A;
458  case cProtocol::pktCameraSetTo: return 0x3E;
459  case cProtocol::pktCollectEntity: return 0x55;
460  case cProtocol::pktDestroyEntity: return 0x37;
461  case cProtocol::pktDisconnectDuringGame: return 0x1A;
462  case cProtocol::pktEntityEffect: return 0x59;
463  case cProtocol::pktEntityEquipment: return 0x46;
464  case cProtocol::pktEntityHeadLook: return 0x3B;
465  case cProtocol::pktEntityMeta: return 0x43;
466  case cProtocol::pktEntityProperties: return 0x58;
467  case cProtocol::pktEntityStatus: return 0x1B;
468  case cProtocol::pktEntityVelocity: return 0x45;
469  case cProtocol::pktExperience: return 0x47;
470  case cProtocol::pktExplosion: return 0x1C;
471  case cProtocol::pktGameMode: return 0x1E;
472  case cProtocol::pktHeldItemChange: return 0x3F;
473  case cProtocol::pktHorseWindowOpen: return 0x1F;
474  case cProtocol::pktInventorySlot: return 0x16;
475  case cProtocol::pktKeepAlive: return 0x20;
476  case cProtocol::pktParticleEffect: return 0x23;
477  case cProtocol::pktPlayerAbilities: return 0x31;
478  case cProtocol::pktPlayerList: return 0x33;
479  case cProtocol::pktPlayerMoveLook: return 0x35;
480  case cProtocol::pktPluginMessage: return 0x18;
481  case cProtocol::pktRemoveEntityEffect: return 0x38;
482  case cProtocol::pktResourcePack: return 0x39;
483  case cProtocol::pktRespawn: return 0x3A;
484  case cProtocol::pktScoreboardObjective: return 0x49;
485  case cProtocol::pktSoundEffect: return 0x19;
486  case cProtocol::pktSoundParticleEffect: return 0x22;
487  case cProtocol::pktSpawnPosition: return 0x4D;
488  case cProtocol::pktTeleportEntity: return 0x56;
489  case cProtocol::pktTimeUpdate: return 0x4E;
490  case cProtocol::pktTitle: return 0x4F;
491  case cProtocol::pktUnloadChunk: return 0x1D;
492  case cProtocol::pktUnlockRecipe: return 0x36;
493  case cProtocol::pktUpdateHealth: return 0x48;
494  case cProtocol::pktUpdateScore: return 0x4C;
495  case cProtocol::pktUpdateSign: return 0x2F;
496  case cProtocol::pktWeather: return 0x1E;
497  case cProtocol::pktWindowItems: return 0x14;
498  case cProtocol::pktWindowOpen: return 0x2E;
499  case cProtocol::pktWindowProperty: return 0x15;
500  default: return Super::GetPacketID(a_PacketType);
501  }
502 }
503 
504 
505 
506 
507 
509 {
510  const UInt8 Entity = 7;
511  const UInt8 Living = Entity + 6;
512  const UInt8 Insentient = Living + 1;
513  const UInt8 Ageable = Insentient + 1;
514  const UInt8 AbstractHorse = Ageable + 2;
515  const UInt8 ChestedHorse = AbstractHorse + 1;
516  const UInt8 TameableAnimal = Ageable + 2;
517  const UInt8 Minecart = Entity + 6;
518  const UInt8 RaidParticipent = Insentient + 1;
519 
520  switch (a_Metadata)
521  {
522  case EntityMetadata::EntityFlags: return 0;
523  case EntityMetadata::EntityAir: return 1;
524  case EntityMetadata::EntityCustomName: return 2;
526  case EntityMetadata::EntitySilent: return 4;
527  case EntityMetadata::EntityNoGravity: return 5;
528  case EntityMetadata::EntityPose: return 6;
529  case EntityMetadata::ThrowableItem: return Entity;
530  case EntityMetadata::PotionThrown: return Entity;
531  case EntityMetadata::FallingBlockPosition: return Entity;
532  case EntityMetadata::AreaEffectCloudRadius: return Entity;
533  case EntityMetadata::AreaEffectCloudColor: return Entity + 1;
534  case EntityMetadata::AreaEffectCloudSinglePointEffect: return Entity + 2;
535  case EntityMetadata::AreaEffectCloudParticleId: return Entity + 3;
536  case EntityMetadata::ArrowFlags: return Entity;
537  case EntityMetadata::PiercingLevel: return Entity + 2;
538  case EntityMetadata::TippedArrowColor: return Entity + 3;
539  case EntityMetadata::BoatLastHitTime: return Entity;
540  case EntityMetadata::BoatForwardDirection: return Entity + 1;
541  case EntityMetadata::BoatDamageTaken: return Entity + 2;
542  case EntityMetadata::BoatType: return Entity + 3;
543  case EntityMetadata::BoatLeftPaddleTurning: return Entity + 4;
544  case EntityMetadata::BoatRightPaddleTurning: return Entity + 5;
545  case EntityMetadata::BoatSplashTimer: return Entity + 6;
546  case EntityMetadata::EnderCrystalBeamTarget: return Entity;
547  case EntityMetadata::EnderCrystalShowBottom: return Entity + 1;
548  case EntityMetadata::WitherSkullInvulnerable: return Entity;
549  case EntityMetadata::FireworkInfo: return Entity;
550  case EntityMetadata::FireworkBoostedEntityId: return Entity + 1;
551  case EntityMetadata::FireworkFromCrossbow: return Entity + 2;
552  case EntityMetadata::ItemFrameItem: return Entity;
553  case EntityMetadata::ItemFrameRotation: return Entity + 1;
554  case EntityMetadata::ItemItem: return Entity;
555  case EntityMetadata::LivingActiveHand: return Entity;
556  case EntityMetadata::LivingHealth: return Entity + 1;
557  case EntityMetadata::LivingPotionEffectColor: return Entity + 2;
558  case EntityMetadata::LivingPotionEffectAmbient: return Entity + 3;
559  case EntityMetadata::LivingNumberOfArrows: return Entity + 4;
560  case EntityMetadata::PlayerAdditionalHearts: return Living;
561  case EntityMetadata::PlayerScore: return Living + 1;
562  case EntityMetadata::PlayerDisplayedSkinParts: return Living + 2;
563  case EntityMetadata::PlayerMainHand: return Living + 3;
564  case EntityMetadata::ArmorStandStatus: return Living;
565  case EntityMetadata::ArmorStandHeadRotation: return Living + 1;
566  case EntityMetadata::ArmorStandBodyRotation: return Living + 2;
567  case EntityMetadata::ArmorStandLeftArmRotation: return Living + 3;
568  case EntityMetadata::ArmorStandRightArmRotation: return Living + 4;
569  case EntityMetadata::ArmorStandLeftLegRotation: return Living + 5;
570  case EntityMetadata::ArmorStandRightLegRotation: return Living + 6;
571  case EntityMetadata::InsentientFlags: return Living;
572  case EntityMetadata::BatHanging: return Insentient;
573  case EntityMetadata::AgeableIsBaby: return Insentient;
574  case EntityMetadata::AbstractHorseFlags: return Ageable;
575  case EntityMetadata::AbstractHorseOwner: return Ageable + 1;
576  case EntityMetadata::HorseVariant: return AbstractHorse;
577  case EntityMetadata::ChestedHorseChested: return AbstractHorse;
578  case EntityMetadata::LlamaStrength: return ChestedHorse;
579  case EntityMetadata::LlamaCarpetColor: return ChestedHorse + 1;
580  case EntityMetadata::LlamaVariant: return ChestedHorse + 2;
581  case EntityMetadata::PigHasSaddle: return Ageable;
582  case EntityMetadata::PigTotalCarrotOnAStickBoost: return Ageable + 1;
583  case EntityMetadata::RabbitType: return Ageable;
584  case EntityMetadata::PolarBearStanding: return Ageable;
585  case EntityMetadata::SheepFlags: return Ageable;
586  case EntityMetadata::TameableAnimalFlags: return Ageable;
587  case EntityMetadata::TameableAnimalOwner: return Ageable + 1;
588  case EntityMetadata::OcelotType: return TameableAnimal;
589  case EntityMetadata::WolfDamageTaken: return TameableAnimal;
590  case EntityMetadata::WolfBegging: return TameableAnimal + 1;
591  case EntityMetadata::WolfCollarColour: return TameableAnimal + 2;
592  case EntityMetadata::VillagerProfession: return Ageable;
593  case EntityMetadata::IronGolemPlayerCreated: return Insentient;
594  case EntityMetadata::ShulkerFacingDirection: return Insentient;
595  case EntityMetadata::ShulkerAttachmentFallingBlockPosition: return Insentient + 1;
596  case EntityMetadata::ShulkerShieldHeight: return Insentient + 2;
597  case EntityMetadata::BlazeOnFire: return Insentient;
598  case EntityMetadata::CreeperState: return Insentient;
599  case EntityMetadata::CreeperPowered: return Insentient + 1;
600  case EntityMetadata::CreeperIgnited: return Insentient + 2;
601  case EntityMetadata::GuardianStatus: return Insentient;
602  case EntityMetadata::GuardianTarget: return Insentient + 1;
603  case EntityMetadata::IllagerFlags: return Insentient;
604  case EntityMetadata::SpeIlagerSpell: return Insentient + 1;
605  case EntityMetadata::VexFlags: return Insentient;
606  case EntityMetadata::AbstractSkeletonArmsSwinging: return Insentient;
607  case EntityMetadata::SpiderClimbing: return Insentient;
608  case EntityMetadata::WitchAggresive: return Insentient;
609  case EntityMetadata::WitherFirstHeadTarget: return Insentient;
610  case EntityMetadata::WitherSecondHeadTarget: return Insentient + 1;
611  case EntityMetadata::WitherThirdHeadTarget: return Insentient + 2;
612  case EntityMetadata::WitherInvulnerableTimer: return Insentient + 3;
613  case EntityMetadata::ZombieIsBaby: return Insentient;
614  case EntityMetadata::ZombieHandsRisedUp: return Insentient + 2;
615  case EntityMetadata::ZombieVillagerConverting: return Insentient + 4;
616  case EntityMetadata::ZombieVillagerProfession: return Insentient + 5;
617  case EntityMetadata::EndermanCarriedBlock: return Insentient;
618  case EntityMetadata::EndermanScreaming: return Insentient + 1;
619  case EntityMetadata::EnderDragonDragonPhase: return Insentient;
620  case EntityMetadata::GhastAttacking: return Insentient;
621  case EntityMetadata::SlimeSize: return Insentient;
622  case EntityMetadata::MinecartShakingPower: return Entity;
623  case EntityMetadata::MinecartShakingDirection: return Entity + 1;
624  case EntityMetadata::MinecartShakingMultiplier: return Entity + 2;
625  case EntityMetadata::MinecartBlockIDMeta: return Entity + 3;
626  case EntityMetadata::MinecartBlockY: return Entity + 4;
627  case EntityMetadata::MinecartShowBlock: return Entity + 5;
631  case EntityMetadata::TNTPrimedFuseTime: return Entity;
632  case EntityMetadata::TridentLoyaltyLevel: return Entity + 3;
633  case EntityMetadata::MooshroomType: return Ageable;
634  case EntityMetadata::WitchDrinking: return RaidParticipent;
635 
639 
640  default:
641  break;
642  }
643  UNREACHABLE("Retrieved invalid metadata for protocol");
644 }
645 
646 
647 
648 
649 
650 std::pair<short, short> cProtocol_1_14::GetItemFromProtocolID(UInt32 a_ProtocolID) const
651 {
652  return PaletteUpgrade::ToItem(Palette_1_14::ToItem(a_ProtocolID));
653 }
654 
655 
656 
657 
658 
660 {
661  return Palette_1_14::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
662 }
663 
664 
665 
666 
667 
669 {
670  switch (a_Animation)
671  {
672  case EntityAnimation::FoxChews: return 45;
673  case EntityAnimation::OcelotTrusts: return 40;
674  case EntityAnimation::OcelotDistrusts: return 41;
675  case EntityAnimation::PawnBerryBushPricks: return 44;
682  case EntityAnimation::PawnTeleports: return 46;
684  case EntityAnimation::RavagerAttacks: return 4;
686  case EntityAnimation::VillagerSweats: return 42;
687  default: return Super::GetProtocolEntityStatus(a_Animation);
688  }
689 }
690 
691 
692 
693 
694 
696 {
697  using Type = cEntity::eEntityType;
698 
699  switch (a_Entity.GetEntityType())
700  {
701  case Type::etEnderCrystal: return 17;
702  case Type::etPickup: return 34;
703  case Type::etFallingBlock: return 25;
704  case Type::etMinecart: return 41;
705  case Type::etBoat: return 5;
706  case Type::etTNT: return 58;
707  case Type::etProjectile:
708  {
709  using PType = cProjectileEntity::eKind;
710  const auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
711 
712  switch (Projectile.GetProjectileKind())
713  {
714  case PType::pkArrow: return 2;
715  case PType::pkSnowball: return 70;
716  case PType::pkEgg: return 78;
717  case PType::pkGhastFireball: return 36;
718  case PType::pkFireCharge: return 68;
719  case PType::pkEnderPearl: return 79;
720  case PType::pkExpBottle: return 80;
721  case PType::pkSplashPotion: return 81;
722  case PType::pkFirework: return 26;
723  case PType::pkWitherSkull: return 92;
724  }
725  break;
726  }
727  case Type::etFloater: return 101;
728  case Type::etItemFrame: return 35;
729  case Type::etLeashKnot: return 37;
730 
731  // Non-objects must not be sent
732  case Type::etEntity:
733  case Type::etPlayer:
734  case Type::etMonster:
735  case Type::etExpOrb:
736  case Type::etPainting: break;
737  }
738  UNREACHABLE("Unhandled entity kind");
739 }
740 
741 
742 
743 
744 
745 UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
746 {
747  return Palette_1_14::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
748 }
749 
750 
751 
752 
753 
755 {
756  switch (a_MobType)
757  {
758  // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
759  case mtInvalidType: return 29;
760  case mtBat: return 3;
761  case mtBlaze: return 4;
762  case mtCat: return 6;
763  case mtCaveSpider: return 7;
764  case mtChicken: return 8;
765  case mtCod: return 9;
766  case mtCow: return 10;
767  case mtCreeper: return 11;
768  case mtDonkey: return 12;
769  case mtDolphin: return 13;
770  case mtDrowned: return 15;
771  case mtElderGuardian: return 16;
772  case mtEnderDragon: return 18;
773  case mtEnderman: return 19;
774  case mtEndermite: return 20;
775  case mtEvoker: return 22;
776  case mtFox: return 27;
777  case mtGhast: return 28;
778  case mtGiant: return 29;
779  case mtGuardian: return 30;
780  case mtHorse: return 31;
781  case mtHusk: return 32;
782  case mtIllusioner: return 33;
783  case mtIronGolem: return 85;
784  case mtLlama: return 38;
785  case mtMagmaCube: return 40;
786  case mtMule: return 48;
787  case mtMooshroom: return 49;
788  case mtOcelot: return 50;
789  case mtPanda: return 52;
790  case mtParrot: return 53;
791  case mtPig: return 54;
792  case mtPufferfish: return 55;
793  case mtPolarBear: return 57;
794  case mtRabbit: return 59;
795  case mtSalmon: return 60;
796  case mtSheep: return 61;
797  case mtShulker: return 62;
798  case mtSilverfish: return 64;
799  case mtSkeleton: return 65;
800  case mtSkeletonHorse: return 66;
801  case mtSlime: return 67;
802  case mtSnowGolem: return 69;
803  case mtSpider: return 72;
804  case mtSquid: return 73;
805  case mtStray: return 74;
806  case mtTraderLlama: return 75;
807  case mtTropicalFish: return 76;
808  case mtTurtle: return 77;
809  case mtVex: return 83;
810  case mtVillager: return 84;
811  case mtVindicator: return 86;
812  case mtPillager: return 87;
813  case mtWanderingTrader: return 88;
814  case mtWitch: return 89;
815  case mtWither: return 90;
816  case mtWitherSkeleton: return 91;
817  case mtWolf: return 93;
818  case mtZombie: return 94;
819  case mtZombieHorse: return 95;
820  case mtZombiePigman: return 56;
821  case mtZombieVillager: return 96;
822  case mtPhantom: return 97;
823  case mtRavager: return 98;
824 
825  default: return 0;
826  }
827 }
828 
829 
830 
831 
832 
833 int cProtocol_1_14::GetProtocolParticleID(const AString & a_ParticleName) const
834 {
835  static const std::unordered_map<AString, int> ParticleMap
836  {
837  // Initialize the ParticleMap:
838  { "ambiantentity", 0 },
839  { "angryvillager", 1 },
840  { "barrier", 2 },
841  { "blockdust", 3 },
842  { "bubble", 4 },
843  { "cloud", 5 },
844  { "crit", 6 },
845  { "damageindicator", 7 },
846  { "dragonbreath", 8 },
847  { "driplava", 9 },
848  { "fallinglava", 10 },
849  { "landinglava", 11 },
850  { "dripwater", 12 },
851  { "fallingwater", 13 },
852  { "dust", 14 },
853  { "effect", 15 },
854  { "elderguardian", 16 },
855  { "enchantedhit", 17 },
856  { "enchant", 18 },
857  { "endrod", 19 },
858  { "entityeffect", 20 },
859  { "explosionemitter", 21 },
860  { "explode", 22 },
861  { "fallingdust", 23 },
862  { "firework", 24 },
863  { "fishing", 25 },
864  { "flame", 26 },
865  { "flash", 27 },
866  { "happyvillager", 28 },
867  { "composter", 29 },
868  { "heart", 30 },
869  { "instanteffect", 31 },
870  { "item", 32 },
871  { "slime", 33 },
872  { "snowball", 34 },
873  { "largesmoke", 35 },
874  { "lava", 36 },
875  { "mycelium", 37 },
876  { "note", 38 },
877  { "poof", 39 },
878  { "portal", 40 },
879  { "rain", 41 },
880  { "smoke", 42 },
881  { "sneeze", 43 },
882  { "spit", 44 },
883  { "squidink", 45 },
884  { "sweepattack", 46 },
885  { "totem", 47 },
886  { "underwater", 48 },
887  { "splash", 49 },
888  { "witch", 50 },
889  { "bubblepop", 51 },
890  { "currentdown", 52 },
891  { "bubblecolumnup", 53 },
892  { "nautilus", 54 },
893  { "dolphin", 55 },
894  { "campfirecosysmoke", 56 },
895  { "campfiresignalsmoke", 57 },
896  };
897 
898 
899  const auto ParticleName = StrToLower(a_ParticleName);
900  const auto FindResult = ParticleMap.find(ParticleName);
901  if (FindResult == ParticleMap.end())
902  {
903  LOGWARNING("Unknown particle: %s", a_ParticleName.c_str());
904  ASSERT(!"Unknown particle");
905  return 0;
906  }
907 
908  return FindResult->second;
909 }
910 
911 
912 
913 
914 
916 {
917  return Palette_1_14::From(a_Statistic);
918 }
919 
920 
921 
922 
923 
925 {
926  return Version::v1_14;
927 }
928 
929 
930 
931 
932 
933 bool cProtocol_1_14::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
934 {
935  if (m_State != State::Game)
936  {
937  return Super::HandlePacket(a_ByteBuffer, a_PacketType);
938  }
939 
940  // Game
941  switch (a_PacketType)
942  {
943  case 0x03: HandlePacketChatMessage(a_ByteBuffer); return true;
944  case 0x04: HandlePacketClientStatus(a_ByteBuffer); return true;
945  case 0x05: HandlePacketClientSettings(a_ByteBuffer); return true;
946  case 0x06: HandlePacketTabComplete(a_ByteBuffer); return true;
947  case 0x07: break; // Confirm transaction - not used in Cuberite
948  case 0x08: HandlePacketEnchantItem(a_ByteBuffer); return true;
949  case 0x09: HandlePacketWindowClick(a_ByteBuffer); return true;
950  case 0x0A: HandlePacketWindowClose(a_ByteBuffer); return true;
951  case 0x0B: HandlePacketPluginMessage(a_ByteBuffer); return true;
952  case 0x0E: HandlePacketUseEntity(a_ByteBuffer); return true;
953  case 0x0F: HandlePacketKeepAlive(a_ByteBuffer); return true;
954  case 0x11: HandlePacketPlayerPos(a_ByteBuffer); return true;
955  case 0x12: HandlePacketPlayerPosLook(a_ByteBuffer); return true;
956  case 0x13: HandlePacketPlayerLook(a_ByteBuffer); return true;
957  case 0x14: HandlePacketPlayer(a_ByteBuffer); return true;
958  case 0x15: HandlePacketVehicleMove(a_ByteBuffer); return true;
959  case 0x16: HandlePacketBoatSteer(a_ByteBuffer); return true;
960  case 0x18: HandleCraftRecipe(a_ByteBuffer); return true;
961  case 0x19: HandlePacketPlayerAbilities(a_ByteBuffer); return true;
962  case 0x1A: HandlePacketBlockDig(a_ByteBuffer); return true;
963  case 0x1C: HandlePacketSteerVehicle(a_ByteBuffer); return true;
964  case 0x1D: HandlePacketCraftingBookData(a_ByteBuffer); return true;
965  case 0x1E: HandlePacketNameItem(a_ByteBuffer); return true;
966  case 0x1F: HandlePacketResourcePackStatus(a_ByteBuffer); return true;
967  case 0x20: HandlePacketAdvancementTab(a_ByteBuffer); return true;
968  case 0x22: HandlePacketSetBeaconEffect(a_ByteBuffer); return true;
969  case 0x23: HandlePacketSlotSelect(a_ByteBuffer); return true;
970  case 0x26: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
971  case 0x2C: HandlePacketBlockPlace(a_ByteBuffer); return true;
972  case 0x2D: HandlePacketUseItem(a_ByteBuffer); return true;
973 
974  default: break;
975  }
976 
977  return Super::HandlePacket(a_ByteBuffer, a_PacketType);
978 }
979 
980 
981 
982 
983 
985 {
986  HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status);
987 
988  int BlockX, BlockY, BlockZ;
989  if (!a_ByteBuffer.ReadXZYPosition64(BlockX, BlockY, BlockZ))
990  {
991  return;
992  }
993 
994  HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Face);
995  m_Client->HandleLeftClick({BlockX, BlockY, BlockZ}, FaceIntToBlockFace(Face), Status);
996 }
997 
998 
999 
1000 
1001 
1003 {
1004  HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Hand);
1005 
1006  int BlockX, BlockY, BlockZ;
1007  if (!a_ByteBuffer.ReadXZYPosition64(BlockX, BlockY, BlockZ))
1008  {
1009  return;
1010  }
1011 
1012  HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Face);
1013  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorX);
1014  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorY);
1015  HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorZ);
1016  HANDLE_READ(a_ByteBuffer, ReadBool, bool, InsideBlock);
1017 
1018  m_Client->HandleRightClick({BlockX, BlockY, BlockZ}, FaceIntToBlockFace(Face), {FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16)}, Hand == 0);
1019 }
1020 
1021 
1022 
1023 
1024 
1026 {
1027 }
1028 
1029 
1030 
1031 
1032 
1033 void cProtocol_1_14::WriteEntityMetadata(cPacketizer & a_Pkt, const EntityMetadata a_Metadata, const EntityMetadataType a_FieldType) const
1034 {
1035  a_Pkt.WriteBEUInt8(GetEntityMetadataID(a_Metadata)); // Index
1036  a_Pkt.WriteBEUInt8(Super::GetEntityMetadataID(a_FieldType)); // Type
1037 }
1038 
1039 
1040 
1041 
1042 
1043 void cProtocol_1_14::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
1044 {
1045  // Common metadata:
1046  Int8 Flags = 0;
1047  if (a_Entity.IsOnFire())
1048  {
1049  Flags |= 0x01;
1050  }
1051  if (a_Entity.IsCrouched())
1052  {
1053  Flags |= 0x02;
1054  }
1055  if (a_Entity.IsSprinting())
1056  {
1057  Flags |= 0x08;
1058  }
1059  if (a_Entity.IsRclking())
1060  {
1061  Flags |= 0x10;
1062  }
1063  if (a_Entity.IsInvisible())
1064  {
1065  Flags |= 0x20;
1066  }
1067  /*
1068  if (a_Entity.IsGlowing())
1069  {
1070  Flags |= 0x40;
1071  }
1072  */
1073  if (a_Entity.IsElytraFlying())
1074  {
1075  Flags |= 0x80;
1076  }
1077 
1079  a_Pkt.WriteBEInt8(Flags);
1080 
1081  switch (a_Entity.GetEntityType())
1082  {
1083  case cEntity::etPlayer:
1084  {
1085  auto & Player = static_cast<const cPlayer &>(a_Entity);
1086 
1087  // TODO Set player custom name to their name.
1088  // Then it's possible to move the custom name of mobs to the entities
1089  // and to remove the "special" player custom name.
1091  a_Pkt.WriteString(Player.GetName());
1092 
1094  a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
1095 
1097  a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
1098 
1100  a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
1101  break;
1102  }
1103  case cEntity::etPickup:
1104  {
1106  WriteItem(a_Pkt, static_cast<const cPickup &>(a_Entity).GetItem());
1107  break;
1108  }
1109  case cEntity::etMinecart:
1110  {
1112 
1113  // The following expression makes Minecarts shake more with less health or higher damage taken
1114  auto & Minecart = static_cast<const cMinecart &>(a_Entity);
1115  auto maxHealth = a_Entity.GetMaxHealth();
1116  auto curHealth = a_Entity.GetHealth();
1117  a_Pkt.WriteVarInt32(static_cast<UInt32>((maxHealth - curHealth) * Minecart.LastDamage() * 4));
1118 
1120  a_Pkt.WriteVarInt32(1); // (doesn't seem to effect anything)
1121 
1123  a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10)); // or damage taken
1124 
1125  if (Minecart.GetPayload() == cMinecart::mpNone)
1126  {
1127  auto & RideableMinecart = static_cast<const cRideableMinecart &>(Minecart);
1128  const cItem & MinecartContent = RideableMinecart.GetContent();
1129  if (!MinecartContent.IsEmpty())
1130  {
1132  int Content = MinecartContent.m_ItemType;
1133  Content |= MinecartContent.m_ItemDamage << 8;
1134  a_Pkt.WriteVarInt32(static_cast<UInt32>(Content));
1135 
1137  a_Pkt.WriteVarInt32(static_cast<UInt32>(RideableMinecart.GetBlockHeight()));
1138 
1140  a_Pkt.WriteBool(true);
1141  }
1142  }
1143  else if (Minecart.GetPayload() == cMinecart::mpFurnace)
1144  {
1146  a_Pkt.WriteBool(static_cast<const cMinecartWithFurnace &>(Minecart).IsFueled());
1147  }
1148  break;
1149  } // case etMinecart
1150 
1151  case cEntity::etProjectile:
1152  {
1153  auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
1154  switch (Projectile.GetProjectileKind())
1155  {
1157  {
1159  a_Pkt.WriteBEInt8(static_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0);
1160 
1161  // TODO: Piercing level
1162  break;
1163  }
1165  {
1166  // TODO
1167  break;
1168  }
1170  {
1171  // TODO
1172  }
1173  default:
1174  {
1175  break;
1176  }
1177  }
1178  break;
1179  } // case etProjectile
1180 
1181  case cEntity::etMonster:
1182  {
1183  WriteMobMetadata(a_Pkt, static_cast<const cMonster &>(a_Entity));
1184  break;
1185  }
1186 
1187  case cEntity::etBoat:
1188  {
1189  auto & Boat = static_cast<const cBoat &>(a_Entity);
1190 
1192  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetLastDamage()));
1193 
1195  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetForwardDirection()));
1196 
1198  a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
1199 
1201  a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetMaterial()));
1202 
1204  a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
1205 
1207  a_Pkt.WriteBool(static_cast<bool>(Boat.IsLeftPaddleUsed()));
1208 
1210  a_Pkt.WriteVarInt32(0);
1211 
1212  break;
1213  } // case etBoat
1214 
1215  case cEntity::etItemFrame:
1216  {
1217  const auto & Frame = static_cast<const cItemFrame &>(a_Entity);
1219  WriteItem(a_Pkt, Frame.GetItem());
1221  a_Pkt.WriteVarInt32(Frame.GetItemRotation());
1222  break;
1223  } // case etItemFrame
1224 
1226  {
1227  const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
1228  if (EnderCrystal.DisplaysBeam())
1229  {
1231  a_Pkt.WriteBool(true); // Dont do a second check if it should display the beam
1232  a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
1233  }
1235  a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
1236  break;
1237  } // case etEnderCrystal
1238 
1239  default:
1240  {
1241  break;
1242  }
1243  }
1244 }
1245 
1246 
1247 
1248 
1249 
1250 void cProtocol_1_14::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
1251 {
1252  // Living Enitiy Metadata
1253  if (a_Mob.HasCustomName())
1254  {
1255  // TODO: As of 1.9 _all_ entities can have custom names; should this be moved up?
1257  a_Pkt.WriteBool(true);
1258  a_Pkt.WriteString(a_Mob.GetCustomName());
1259 
1261  a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible());
1262  }
1263 
1265  a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));
1266 
1267  // TODO: pose
1268 
1269  switch (a_Mob.GetMobType())
1270  {
1271  case mtBat:
1272  {
1273  auto & Bat = static_cast<const cBat &>(a_Mob);
1274 
1276  a_Pkt.WriteBEInt8(Bat.IsHanging() ? 1 : 0);
1277  break;
1278  } // case mtBat
1279 
1280  case mtChicken:
1281  {
1282  auto & Chicken = static_cast<const cChicken &>(a_Mob);
1283 
1285  a_Pkt.WriteBool(Chicken.IsBaby());
1286  break;
1287  } // case mtChicken
1288 
1289  case mtCow:
1290  {
1291  auto & Cow = static_cast<const cCow &>(a_Mob);
1292 
1294  a_Pkt.WriteBool(Cow.IsBaby());
1295  break;
1296  } // case mtCow
1297 
1298  case mtCreeper:
1299  {
1300  auto & Creeper = static_cast<const cCreeper &>(a_Mob);
1301 
1303  a_Pkt.WriteVarInt32(Creeper.IsBlowing() ? 1 : static_cast<UInt32>(-1)); // (idle or "blowing")
1304 
1306  a_Pkt.WriteBool(Creeper.IsCharged());
1307 
1309  a_Pkt.WriteBool(Creeper.IsBurnedWithFlintAndSteel());
1310  break;
1311  } // case mtCreeper
1312 
1313  case mtEnderman:
1314  {
1315  auto & Enderman = static_cast<const cEnderman &>(a_Mob);
1317  UInt32 Carried = 0;
1318  Carried |= static_cast<UInt32>(Enderman.GetCarriedBlock() << 4);
1319  Carried |= Enderman.GetCarriedMeta();
1320  a_Pkt.WriteVarInt32(Carried);
1321 
1323  a_Pkt.WriteBool(Enderman.IsScreaming());
1324  break;
1325  } // case mtEnderman
1326 
1327  case mtGhast:
1328  {
1329  auto & Ghast = static_cast<const cGhast &>(a_Mob);
1330 
1332  a_Pkt.WriteBool(Ghast.IsCharging());
1333  break;
1334  } // case mtGhast
1335 
1336  case mtHorse:
1337  {
1338  // XXX This behaves incorrectly with different varients; horses have different entity IDs now
1339 
1340  // Abstract horse
1341  auto & Horse = static_cast<const cHorse &>(a_Mob);
1342 
1343  Int8 Flags = 0;
1344  if (Horse.IsTame())
1345  {
1346  Flags |= 0x02;
1347  }
1348  if (Horse.IsSaddled())
1349  {
1350  Flags |= 0x04;
1351  }
1352  if (Horse.IsInLoveCooldown())
1353  {
1354  Flags |= 0x08;
1355  }
1356  if (Horse.IsEating())
1357  {
1358  Flags |= 0x10;
1359  }
1360  if (Horse.IsRearing())
1361  {
1362  Flags |= 0x20;
1363  }
1364  if (Horse.IsMthOpen())
1365  {
1366  Flags |= 0x40;
1367  }
1369  a_Pkt.WriteBEInt8(Flags);
1370 
1371  // Regular horses
1372  int Appearance = 0;
1373  Appearance = Horse.GetHorseColor();
1374  Appearance |= Horse.GetHorseStyle() << 8;
1376  a_Pkt.WriteVarInt32(static_cast<UInt32>(Appearance)); // Color / style
1377 
1379  a_Pkt.WriteBool(Horse.IsBaby());
1380  break;
1381  } // case mtHorse
1382 
1383  case mtMagmaCube:
1384  {
1385  auto & MagmaCube = static_cast<const cMagmaCube &>(a_Mob);
1386 
1388  a_Pkt.WriteVarInt32(static_cast<UInt32>(MagmaCube.GetSize()));
1389  break;
1390  } // case mtMagmaCube
1391 
1392  case mtOcelot:
1393  {
1394  auto & Ocelot = static_cast<const cOcelot &>(a_Mob);
1395 
1397  a_Pkt.WriteBool(Ocelot.IsBaby());
1398 
1399  // TODO: Ocelot trusting
1400 
1401  break;
1402  } // case mtOcelot
1403 
1404  case mtPig:
1405  {
1406  auto & Pig = static_cast<const cPig &>(a_Mob);
1407 
1409  a_Pkt.WriteBool(Pig.IsBaby());
1410 
1412  a_Pkt.WriteBool(Pig.IsSaddled());
1413 
1414  // PIG_TOTAL_CARROT_ON_A_STICK_BOOST in 1.11.1 only
1415  break;
1416  } // case mtPig
1417 
1418  case mtRabbit:
1419  {
1420  auto & Rabbit = static_cast<const cRabbit &>(a_Mob);
1421 
1423  a_Pkt.WriteBool(Rabbit.IsBaby());
1424 
1426  a_Pkt.WriteVarInt32(static_cast<UInt32>(Rabbit.GetRabbitType()));
1427  break;
1428  } // case mtRabbit
1429 
1430  case mtSheep:
1431  {
1432  auto & Sheep = static_cast<const cSheep &>(a_Mob);
1433 
1435  a_Pkt.WriteBool(Sheep.IsBaby());
1436 
1437  Int8 SheepMetadata = 0;
1438  SheepMetadata = static_cast<Int8>(Sheep.GetFurColor());
1439  if (Sheep.IsSheared())
1440  {
1441  SheepMetadata |= 0x10;
1442  }
1444  a_Pkt.WriteBEInt8(SheepMetadata);
1445  break;
1446  } // case mtSheep
1447 
1448  case mtSkeleton:
1449  {
1450  auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
1452  a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
1453 
1454  // TODO: Skeleton animation
1455  break;
1456  } // case mtSkeleton
1457 
1458  case mtSlime:
1459  {
1460  auto & Slime = static_cast<const cSlime &>(a_Mob);
1461 
1463  a_Pkt.WriteVarInt32(static_cast<UInt32>(Slime.GetSize()));
1464  break;
1465  } // case mtSlime
1466 
1467  case mtVillager:
1468  {
1469  auto & Villager = static_cast<const cVillager &>(a_Mob);
1470 
1472  a_Pkt.WriteBool(Villager.IsBaby());
1473 
1475  a_Pkt.WriteVarInt32(2); // Villager from plains
1476  switch (Villager.GetVilType())
1477  {
1478  case cVillager::vtFarmer:
1479  {
1480  a_Pkt.WriteVarInt32(5);
1481  break;
1482  }
1484  {
1485  a_Pkt.WriteVarInt32(9);
1486  break;
1487  }
1488  case cVillager::vtPriest:
1489  {
1490  a_Pkt.WriteVarInt32(4);
1491  break;
1492  }
1494  {
1495  a_Pkt.WriteVarInt32(13);
1496  break;
1497  }
1498  case cVillager::vtButcher:
1499  {
1500  a_Pkt.WriteVarInt32(2);
1501  break;
1502  }
1503  case cVillager::vtGeneric:
1504  {
1505  a_Pkt.WriteVarInt32(0);
1506  break;
1507  }
1508  }
1509  a_Pkt.WriteVarInt32(1); // Level 1 villager
1510  break;
1511  } // case mtVillager
1512 
1513  case mtWitch:
1514  {
1515  // auto & Witch = static_cast<const cWitch &>(a_Mob);
1516 
1517  // TODO: Witch drinking potion
1518  break;
1519  } // case mtWitch
1520 
1521  case mtWither:
1522  {
1523  auto & Wither = static_cast<const cWither &>(a_Mob);
1524 
1526  a_Pkt.WriteVarInt32(Wither.GetWitherInvulnerableTicks());
1527 
1528  // TODO: Use boss bar packet for health
1529  break;
1530  } // case mtWither
1531 
1532  case mtWolf:
1533  {
1534  auto & Wolf = static_cast<const cWolf &>(a_Mob);
1535 
1537  a_Pkt.WriteBool(Wolf.IsBaby());
1538 
1539  Int8 WolfStatus = 0;
1540  if (Wolf.IsSitting())
1541  {
1542  WolfStatus |= 0x1;
1543  }
1544  if (Wolf.IsAngry())
1545  {
1546  WolfStatus |= 0x2;
1547  }
1548  if (Wolf.IsTame())
1549  {
1550  WolfStatus |= 0x4;
1551  }
1553  a_Pkt.WriteBEInt8(WolfStatus);
1554 
1556  a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); // TODO Not use the current health
1557 
1559  a_Pkt.WriteBool(Wolf.IsBegging());
1560 
1562  a_Pkt.WriteVarInt32(static_cast<UInt32>(Wolf.GetCollarColor()));
1563  break;
1564  } // case mtWolf
1565 
1566  case mtZombie:
1567  {
1568  // XXX Zombies were also split into new sublcasses; this doesn't handle that.
1569 
1570  auto & Zombie = static_cast<const cZombie &>(a_Mob);
1571 
1573  a_Pkt.WriteBool(Zombie.IsBaby());
1574  break;
1575  } // case mtZombie
1576 
1577  case mtZombiePigman:
1578  {
1579  auto & ZombiePigman = static_cast<const cZombiePigman &>(a_Mob);
1580 
1582  a_Pkt.WriteBool(ZombiePigman.IsBaby());
1583  break;
1584  } // case mtZombiePigman
1585 
1586  case mtBlaze:
1587  case mtEnderDragon:
1588  case mtIronGolem:
1589  case mtSnowGolem:
1590  case mtSpider:
1591  case mtZombieVillager:
1592 
1593  case mtElderGuardian:
1594  case mtGuardian:
1595  {
1596  // TODO: Mobs with extra fields that aren't implemented
1597  break;
1598  }
1599 
1600  case mtCat:
1601 
1602  case mtCod:
1603 
1604  case mtDolphin:
1605 
1606  case mtDonkey:
1607 
1608  case mtDrowned:
1609 
1610  case mtEvoker:
1611 
1612  case mtIllusioner:
1613 
1614  case mtLlama:
1615 
1616  case mtMule:
1617 
1618  case mtParrot:
1619 
1620  case mtPhantom:
1621 
1622  case mtPolarBear:
1623 
1624  case mtPufferfish:
1625 
1626  case mtSalmon:
1627 
1628  case mtShulker:
1629 
1630  case mtStray:
1631 
1632  case mtSkeletonHorse:
1633  case mtZombieHorse:
1634 
1635  case mtTropicalFish:
1636 
1637  case mtTurtle:
1638 
1639  case mtVex:
1640 
1641  case mtVindicator:
1642 
1643  case mtHusk:
1644  {
1645  // Todo: Mobs not added yet. Grouped ones have the same metadata
1646  ASSERT(!"cProtocol_1_14::WriteMobMetadata: received unimplemented type");
1647  break;
1648  }
1649 
1650  case mtMooshroom:
1651  case mtCaveSpider:
1652  {
1653  // Not mentioned on http://wiki.vg/Entities
1654  break;
1655  }
1656 
1657  case mtEndermite:
1658  case mtGiant:
1659  case mtSilverfish:
1660  case mtSquid:
1661  case mtWitherSkeleton:
1662  {
1663  // Mobs with no extra fields
1664  break;
1665  }
1666 
1667  default: UNREACHABLE("cProtocol_1_14::WriteMobMetadata: received mob of invalid type");
1668  } // switch (a_Mob.GetType())
1669 }
1670 
1671 
1672 
1673 
1674 
1676 // cProtocol_1_14_1:
1677 
1679 {
1680  return Version::v1_14_1;
1681 }
1682 
1683 
1684 
1685 
1686 
1688 // cProtocol_1_14_2:
1689 
1691 {
1692  return Version::v1_14_2;
1693 }
1694 
1695 
1696 
1697 
1698 
1700 // cProtocol_1_14_3:
1701 
1703 {
1704  return Version::v1_14_3;
1705 }
1706 
1707 
1708 
1709 
1710 
1712 // cProtocol_1_14_4:
1713 
1715 {
1716  return Version::v1_14_4;
1717 }
@ 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_SIGN_POST
Definition: BlockType.h:76
@ 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_END_GATEWAY
Definition: BlockType.h:228
@ E_BLOCK_BED
Definition: BlockType.h:36
@ E_BLOCK_END_PORTAL
Definition: BlockType.h:134
@ E_BLOCK_MOB_SPAWNER
Definition: BlockType.h:62
@ E_BLOCK_WALL_BANNER
Definition: BlockType.h:196
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
EntityAnimation
Definition: Defines.h:458
eDimension
Dimension of a world.
Definition: Defines.h:231
EffectID
Definition: EffectID.h:6
#define UNREACHABLE(x)
Definition: Globals.h:288
auto ToUnsigned(T a_Val)
Definition: Globals.h:387
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
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
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
@ mtTurtle
Definition: MonsterTypes.h:69
@ mtPolarBear
Definition: MonsterTypes.h:51
@ mtDolphin
Definition: MonsterTypes.h:22
@ mtMagmaCube
Definition: MonsterTypes.h:40
@ mtWanderingTrader
Definition: MonsterTypes.h:73
@ 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
@ mtRavager
Definition: MonsterTypes.h:54
@ mtDonkey
Definition: MonsterTypes.h:23
@ mtVex
Definition: MonsterTypes.h:70
@ mtEnderman
Definition: MonsterTypes.h:27
@ mtTropicalFish
Definition: MonsterTypes.h:68
@ mtHusk
Definition: MonsterTypes.h:36
@ mtCaveSpider
Definition: MonsterTypes.h:17
@ mtEvoker
Definition: MonsterTypes.h:29
@ mtPhantom
Definition: MonsterTypes.h:46
@ mtShulker
Definition: MonsterTypes.h:57
@ mtPufferfish
Definition: MonsterTypes.h:52
@ mtWither
Definition: MonsterTypes.h:75
@ mtSkeletonHorse
Definition: MonsterTypes.h:60
@ mtPig
Definition: MonsterTypes.h:47
@ mtDrowned
Definition: MonsterTypes.h:24
@ 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
@ mtSalmon
Definition: MonsterTypes.h:55
@ 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
@ mtIllusioner
Definition: MonsterTypes.h:37
@ mtChicken
Definition: MonsterTypes.h:18
@ mtGiant
Definition: MonsterTypes.h:32
@ mtSnowGolem
Definition: MonsterTypes.h:62
@ mtFox
Definition: MonsterTypes.h:30
@ 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
@ mtPillager
Definition: MonsterTypes.h:50
@ mtGhast
Definition: MonsterTypes.h:31
@ mtParrot
Definition: MonsterTypes.h:45
@ mtSilverfish
Definition: MonsterTypes.h:58
@ mtPanda
Definition: MonsterTypes.h:44
@ mtCod
Definition: MonsterTypes.h:19
@ 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
CustomStatistic
@ Rabbit
@ Chicken
@ Minecart
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
std::string AString
Definition: StringUtils.h:11
AString SerializeSingleValueJsonObject(const AString &a_Key, const AString &a_Value)
Creates a Json string representing an object with the specified single value.
Definition: JsonUtils.cpp:47
Item ToItem(const UInt32 ID)
UInt32 From(const BlockState Block)
Definition: Palette_1_14.cpp:8
Item FromItem(const short Item, const short Damage)
Definition: Upgrade.cpp:1708
std::pair< short, short > ToItem(const Item ID)
Definition: Upgrade.cpp:2519
BlockState FromBlock(const BLOCKTYPE Block, const NIBBLETYPE Meta)
Definition: Upgrade.cpp:8
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 ReadXZYPosition64(int &a_BlockX, int &a_BlockY, int &a_BlockZ)
Definition: ByteBuffer.cpp:539
void HandleLeftClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, UInt8 a_Status)
void HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_Cursor, bool a_UsedMainHand)
cPlayer * GetPlayer(void)
Definition: ClientHandle.h:78
Definition: Boat.h:20
Definition: Entity.h:76
virtual bool IsElytraFlying(void) const
Definition: Entity.h:487
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
double GetPosX(void) const
Definition: Entity.h:195
double GetPosZ(void) const
Definition: Entity.h:197
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 GetPosY(void) const
Definition: Entity.h:196
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
eEntityType
Definition: Entity.h:89
@ 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
Definition: Pickup.h:20
Definition: Player.h:29
eGameMode GetEffectiveGameMode(void) const
Returns the current effective gamemode (inherited gamemode is resolved before returning)
Definition: Player.cpp:1531
eKind
The kind of the projectile.
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
Encapsulates an in-game world map.
Definition: Map.h:83
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
Definition: Ocelot.h:13
Definition: Pig.h:12
Definition: Rabbit.h:27
Definition: Sheep.h:12
Definition: Slime.h:12
@ vtPriest
Definition: Villager.h:22
@ vtFarmer
Definition: Villager.h:20
@ vtGeneric
Definition: Villager.h:25
@ vtBlacksmith
Definition: Villager.h:23
@ vtLibrarian
Definition: Villager.h:21
@ vtButcher
Definition: Villager.h:24
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 WriteBEUInt32(UInt32 a_Value)
Definition: Packetizer.h:111
void WriteBEInt32(Int32 a_Value)
Definition: Packetizer.h:105
void WriteXZYPosition64(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:175
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
EntityMetadataType
Definition: Protocol.h:311
ePacketType
Logical types of outgoing packets.
Definition: Protocol.h:57
@ pktUnloadChunk
Definition: Protocol.h:123
@ pktEntityHeadLook
Definition: Protocol.h:77
@ pktSoundEffect
Definition: Protocol.h:108
@ pktSoundParticleEffect
Definition: Protocol.h:109
@ pktEntityVelocity
Definition: Protocol.h:84
@ pktEntityMeta
Definition: Protocol.h:79
@ pktAttachEntity
Definition: Protocol.h:58
@ pktResourcePack
Definition: Protocol.h:104
@ pktKeepAlive
Definition: Protocol.h:92
@ pktInventorySlot
Definition: Protocol.h:90
@ pktParticleEffect
Definition: Protocol.h:96
@ pktCameraSetTo
Definition: Protocol.h:64
@ pktEntityEffect
Definition: Protocol.h:75
@ pktTeleportEntity
Definition: Protocol.h:120
@ pktUpdateBlockEntity
Definition: Protocol.h:125
@ pktPluginMessage
Definition: Protocol.h:102
@ pktSpawnObject
Definition: Protocol.h:107
@ pktPlayerMoveLook
Definition: Protocol.h:101
@ pktSpawnPosition
Definition: Protocol.h:115
@ pktTimeUpdate
Definition: Protocol.h:121
@ pktPlayerList
Definition: Protocol.h:99
@ pktJoinGame
Definition: Protocol.h:91
@ pktExplosion
Definition: Protocol.h:86
@ pktDifficulty
Definition: Protocol.h:68
@ pktDestroyEntity
Definition: Protocol.h:67
@ pktUpdateHealth
Definition: Protocol.h:126
@ pktUpdateScore
Definition: Protocol.h:127
@ pktHorseWindowOpen
Definition: Protocol.h:89
@ pktEntityEquipment
Definition: Protocol.h:76
@ pktWindowOpen
Definition: Protocol.h:133
@ pktUpdateSign
Definition: Protocol.h:128
@ pktRespawn
Definition: Protocol.h:105
@ pktWindowProperty
Definition: Protocol.h:134
@ pktEntityProperties
Definition: Protocol.h:80
@ pktEntityStatus
Definition: Protocol.h:83
@ pktScoreboardObjective
Definition: Protocol.h:106
@ pktCollectEntity
Definition: Protocol.h:66
@ pktBlockChange
Definition: Protocol.h:61
@ pktRemoveEntityEffect
Definition: Protocol.h:103
@ pktUnlockRecipe
Definition: Protocol.h:124
@ pktBlockBreakAnim
Definition: Protocol.h:60
@ pktHeldItemChange
Definition: Protocol.h:88
@ pktDisconnectDuringGame
Definition: Protocol.h:70
@ pktTitle
Definition: Protocol.h:122
@ pktPlayerAbilities
Definition: Protocol.h:98
@ pktWeather
Definition: Protocol.h:130
@ pktExperience
Definition: Protocol.h:85
@ pktGameMode
Definition: Protocol.h:87
@ pktBlockAction
Definition: Protocol.h:59
@ pktWindowItems
Definition: Protocol.h:131
Version
The protocol version number, received from the client in the Handshake packet.
Definition: Protocol.h:335
EntityMetadata
Definition: Protocol.h:138
cClientHandle * m_Client
Definition: Protocol.h:472
virtual void HandlePacketResourcePackStatus(cByteBuffer &a_ByteBuffer) 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 HandleCraftRecipe(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketAdvancementTab(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketCraftingBookData(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketKeepAlive(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketNameItem(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketSetBeaconEffect(cByteBuffer &a_ByteBuffer)
virtual bool HandlePacket(cByteBuffer &a_ByteBuffer, UInt32 a_PacketType) override
Reads and handles the packet.
virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata) const
virtual void HandlePacketPluginMessage(cByteBuffer &a_ByteBuffer) 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 GetPacketID(ePacketType a_PacketType) const override
Get the packet ID for a given packet.
virtual void WriteItem(cPacketizer &a_Pkt, const cItem &a_Item) const override
Writes the item data into a packet.
virtual void SendWindowOpen(const cWindow &a_Window) override
virtual void WriteEntityMetadata(cPacketizer &a_Pkt, EntityMetadata a_Metadata, EntityMetadataType a_FieldType) const override
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual void HandlePacketBlockPlace(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketUpdateSign(cByteBuffer &a_ByteBuffer) override
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override
Converts eMonsterType to protocol-specific mob types.
virtual void SendBlockBreakAnim(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage) override
virtual void SendRespawn(eDimension a_Dimension) override
virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const override
virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata) const override
virtual void SendParticleEffect(const AString &a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array< int, 2 > a_Data) override
virtual void SendUpdateSign(Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4) override
virtual bool HandlePacket(cByteBuffer &a_ByteBuffer, UInt32 a_PacketType) override
Reads and handles the packet.
virtual void SendSoundParticleEffect(const EffectID a_EffectID, Vector3i a_Origin, int a_Data) override
virtual void SendPaintingSpawn(const cPainting &a_Painting) override
virtual void SendUpdateBlockEntity(cBlockEntity &a_BlockEntity) override
virtual void SendMapData(const cMap &a_Map, int a_DataStartX, int a_DataStartY) override
virtual void SendLogin(const cPlayer &a_Player, const cWorld &a_World) override
virtual UInt8 GetProtocolEntityType(const cEntity &a_Entity) const override
Converts an entity to a protocol-specific entity type.
virtual std::pair< short, short > GetItemFromProtocolID(UInt32 a_ProtocolID) const override
virtual int GetProtocolParticleID(const AString &a_ParticleName) const override
The 1.8 protocol use a particle id instead of a string.
virtual void SendEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation) 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 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override
virtual void SendBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override
virtual void HandlePacketBlockDig(cByteBuffer &a_ByteBuffer) override
virtual void WriteMobMetadata(cPacketizer &a_Pkt, const cMonster &a_Mob) const override
Writes the mob-specific metadata for the specified mob.
virtual void SendEditSign(Vector3i a_BlockPos) override
Request the client to open up the sign editor for the sign (1.6+)
virtual void SendBlockChange(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
virtual void SendEntitySpawn(const cEntity &a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override
Sends the entity type and entity-dependent data required for the entity to initially spawn.
virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override
virtual UInt32 GetPacketID(ePacketType a_PacketType) const override
Get the packet ID for a given packet.
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual Version GetProtocolVersion() const override
Returns the protocol version.
virtual void HandlePacketPlayer(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketEnchantItem(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketCreativeInventoryAction(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketWindowClose(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketPlayerAbilities(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketChatMessage(cByteBuffer &a_ByteBuffer)
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 HandlePacketPlayerLook(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketClientStatus(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketSlotSelect(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketSteerVehicle(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketUseEntity(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketPlayerPos(cByteBuffer &a_ByteBuffer) override
virtual void SendEntityMetadata(const cEntity &a_Entity) override
virtual void HandlePacketUseItem(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketWindowClick(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketClientSettings(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketPlayerPosLook(cByteBuffer &a_ByteBuffer) override
virtual void HandlePacketBoatSteer(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketVehicleMove(cByteBuffer &a_ByteBuffer)
virtual void HandlePacketTabComplete(cByteBuffer &a_ByteBuffer) override
cServer * GetServer(void)
Definition: Root.h:71
static cRoot * Get()
Definition: Root.h:52
Definition: Server.h:56
size_t GetMaxPlayers(void) const
Definition: Server.h:70
bool IsHardcore(void) const
Definition: Server.h:93
Represents a UI window.
Definition: Window.h:54
@ wtDropSpenser
Definition: Window.h:62
@ wtNPCTrade
Definition: Window.h:65
@ wtDropper
Definition: Window.h:69
@ wtWorkbench
Definition: Window.h:60
@ wtFurnace
Definition: Window.h:61
@ wtAnvil
Definition: Window.h:67
@ wtHopper
Definition: Window.h:68
@ wtBeacon
Definition: Window.h:66
@ wtAnimalChest
Definition: Window.h:70
@ wtEnchantment
Definition: Window.h:63
@ wtBrewery
Definition: Window.h:64
@ wtChest
Definition: Window.h:59
int GetNumNonInventorySlots(void) const
Returns the number of slots, excluding the player's inventory (used for network protocols)
Definition: Window.h:93
int GetNumSlots(void) const
Returns the total number of slots.
Definition: Window.cpp:90
char GetWindowID(void) const
Definition: Window.h:80
const AString & GetWindowTitle() const
Definition: Window.h:140
int GetWindowType(void) const
Definition: Window.h:81
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
Definition: World.h:53
int GetSpawnX(void) const
Definition: World.h:585
int GetSpawnZ(void) const
Definition: World.h:587
int GetMaxViewDistance(void) const
Definition: World.h:711
virtual eDimension GetDimension(void) const override
Definition: World.h:133
int GetSpawnY(void) const
Definition: World.h:586
void Finish(void)
Definition: FastNBT.cpp:674
ContiguousByteBufferView GetResult(void) const
Definition: FastNBT.h:351