diff options
author | LogicParrot <LogicParrot@users.noreply.github.com> | 2017-08-22 14:15:36 +0200 |
---|---|---|
committer | LogicParrot <LogicParrot@users.noreply.github.com> | 2017-08-22 19:55:30 +0200 |
commit | 18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e (patch) | |
tree | 221db2c2a9f4c3388f50edf79d38448ca1a0e4a2 /src | |
parent | d (diff) | |
download | cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.gz cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.bz2 cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.lz cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.xz cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.zst cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/Mobs/Bat.cpp | 9 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.cpp | 304 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.h | 54 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorItemFollower.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorItemFollower.h | 10 | ||||
-rw-r--r-- | src/Mobs/Blaze.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/CaveSpider.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Chicken.cpp | 88 | ||||
-rw-r--r-- | src/Mobs/Chicken.h | 24 | ||||
-rw-r--r-- | src/Mobs/Cow.cpp | 42 | ||||
-rw-r--r-- | src/Mobs/Cow.h | 20 | ||||
-rw-r--r-- | src/Mobs/Creeper.cpp | 1 | ||||
-rw-r--r-- | src/Mobs/Creeper.h | 27 | ||||
-rw-r--r-- | src/Mobs/Ghast.cpp | 56 | ||||
-rw-r--r-- | src/Mobs/Ghast.h | 13 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 11 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 6 | ||||
-rw-r--r-- | src/Mobs/PassiveMonster.cpp | 4 | ||||
-rw-r--r-- | src/Mobs/PassiveMonster.h | 4 | ||||
-rw-r--r-- | src/Mobs/Silverfish.h | 14 | ||||
-rw-r--r-- | src/Mobs/Skeleton.cpp | 94 | ||||
-rw-r--r-- | src/Mobs/Skeleton.h | 20 | ||||
-rw-r--r-- | src/Mobs/Slime.cpp | 114 | ||||
-rw-r--r-- | src/Mobs/Slime.h | 32 | ||||
-rw-r--r-- | src/Mobs/Spider.cpp | 92 | ||||
-rw-r--r-- | src/Mobs/Wolf.cpp | 656 | ||||
-rw-r--r-- | src/Mobs/Wolf.h | 104 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_8.cpp | 4758 |
28 files changed, 3276 insertions, 3287 deletions
diff --git a/src/Mobs/Bat.cpp b/src/Mobs/Bat.cpp index e419ceb2d..906b99320 100644 --- a/src/Mobs/Bat.cpp +++ b/src/Mobs/Bat.cpp @@ -4,12 +4,13 @@ #include "Bat.h" #include "../Chunk.h" - cBat::cBat(void) : - super("Bat", mtBat, "entity.bat.hurt", "entity.bat.death", 0.5, 0.9) + super("Bat", mtBat, "entity.bat.hurt", "entity.bat.death", 0.5, 0.9) { - SetGravity(-2.0f); - SetAirDrag(0.05f); + SetGravity(-2.0f); + SetAirDrag(0.05f); + + } diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp index ea3e10026..ddca1715a 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.cpp +++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp @@ -9,25 +9,15 @@ #include "../../Item.h" #include "../../BoundingBox.h" -iBehaviorBreeder::~iBehaviorBreeder() +cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent) : + m_Parent(a_Parent), + m_LovePartner(nullptr), + m_LoveTimer(0), + m_LoveCooldown(0), + m_MatingTimer(0), { - -} - - - - - -cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems) : - m_Parent(a_Parent), - m_LovePartner(nullptr), - m_LoveTimer(0), - m_LoveCooldown(0), - m_MatingTimer(0), - m_BreedingItems(a_BreedingItems) -{ - m_Parent = dynamic_cast<cMonster *>(m_ParentInterface); - ASSERT(m_Parent != nullptr); + m_Parent = a_Parent; + ASSERT(m_Parent != nullptr); } @@ -36,105 +26,105 @@ cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems bool cBehaviorBreeder::ActiveTick() { - cWorld * World = m_Parent->GetWorld(); - // if we have a partner, mate - if (m_LovePartner != nullptr) - { - if (m_MatingTimer > 0) - { - // If we should still mate, keep bumping into them until baby is made - Vector3d Pos = m_LovePartner->GetPosition(); - m_Parent->MoveToPosition(Pos); - } - else - { - // Mating finished. Spawn baby - Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5; - UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true); - - class cBabyInheritCallback : - public cEntityCallback - { - public: - cMonster * Baby; - cBabyInheritCallback() : Baby(nullptr) { } - virtual bool Item(cEntity * a_Entity) override - { - Baby = static_cast<cMonster *>(a_Entity); - return true; - } - } Callback; - - m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback); - if (Callback.Baby != nullptr) - { - Callback.Baby->InheritFromParents(m_Parent, m_LovePartner); - } - - cFastRandom Random; - World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + Random.NextInt(6)); - - m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); - ResetLoveMode(); - } - return true; - } - - // If we are in love mode and we have no partner - if (m_LoveTimer > 0) - { - class LookForLover : public cEntityCallback - { - public: - cMonster * m_Me; - LookForLover(cMonster * a_Me) : - m_Me(a_Me) - { - } - - virtual bool Item(cEntity * a_Entity) override - { - // If the entity is not a monster, don't breed with it - // Also, do not self-breed - if ((a_Entity->GetEntityType() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me)) - { - return false; - } - - auto PotentialPartner = static_cast<cMonster*>(a_Entity); - - // If the potential partner is not of the same species, don't breed with it - if (PotentialPartner->GetMobType() != m_Me->GetMobType()) - { - return false; - } - - auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder(); - auto MyBreedingBehavior = m_Me->GetBehaviorBreeder(); - - // If the potential partner is not in love - // Or they already have a mate, do not breed with them - - if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr)) - { - return false; - } - - // All conditions met, let's breed! - PartnerBreedingBehavior->EngageLoveMode(m_Me); - MyBreedingBehavior->EngageLoveMode(PotentialPartner); - return true; - } - } Callback(m_Parent); - - World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback); - if (m_LovePartner != nullptr) - { - return true; // We found love and took control of the monster, prevent other Behaviors from doing so - } - } - - return false; + cWorld * World = m_Parent->GetWorld(); + // if we have a partner, mate + if (m_LovePartner != nullptr) + { + if (m_MatingTimer > 0) + { + // If we should still mate, keep bumping into them until baby is made + Vector3d Pos = m_LovePartner->GetPosition(); + m_Parent->MoveToPosition(Pos); + } + else + { + // Mating finished. Spawn baby + Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5; + UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true); + + class cBabyInheritCallback : + public cEntityCallback + { + public: + cMonster * Baby; + cBabyInheritCallback() : Baby(nullptr) { } + virtual bool Item(cEntity * a_Entity) override + { + Baby = static_cast<cMonster *>(a_Entity); + return true; + } + } Callback; + + m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback); + if (Callback.Baby != nullptr) + { + Callback.Baby->InheritFromParents(m_Parent, m_LovePartner); + } + + cFastRandom Random; + World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + Random.NextInt(6)); + + m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); + ResetLoveMode(); + } + return true; + } + + // If we are in love mode and we have no partner + if (m_LoveTimer > 0) + { + class LookForLover : public cEntityCallback + { + public: + cMonster * m_Me; + LookForLover(cMonster * a_Me) : + m_Me(a_Me) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + // If the entity is not a monster, don't breed with it + // Also, do not self-breed + if ((a_Entity->GetEntityType() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me)) + { + return false; + } + + auto PotentialPartner = static_cast<cMonster*>(a_Entity); + + // If the potential partner is not of the same species, don't breed with it + if (PotentialPartner->GetMobType() != m_Me->GetMobType()) + { + return false; + } + + auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder(); + auto MyBreedingBehavior = m_Me->GetBehaviorBreeder(); + + // If the potential partner is not in love + // Or they already have a mate, do not breed with them + + if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr)) + { + return false; + } + + // All conditions met, let's breed! + PartnerBreedingBehavior->EngageLoveMode(m_Me); + MyBreedingBehavior->EngageLoveMode(PotentialPartner); + return true; + } + } Callback(m_Parent); + + World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback); + if (m_LovePartner != nullptr) + { + return true; // We found love and took control of the monster, prevent other Behaviors from doing so + } + } + + return false; } @@ -143,18 +133,18 @@ bool cBehaviorBreeder::ActiveTick() void cBehaviorBreeder::Tick() { - if (m_MatingTimer > 0) - { - m_MatingTimer--; - } - if (m_LoveCooldown > 0) - { - m_LoveCooldown--; - } - if (m_LoveTimer > 0) - { - m_LoveTimer--; - } + if (m_MatingTimer > 0) + { + m_MatingTimer--; + } + if (m_LoveCooldown > 0) + { + m_LoveCooldown--; + } + if (m_LoveTimer > 0) + { + m_LoveTimer--; + } } @@ -163,10 +153,10 @@ void cBehaviorBreeder::Tick() void cBehaviorBreeder::Destroyed() { - if (m_LovePartner != nullptr) - { - m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); - } + if (m_LovePartner != nullptr) + { + m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); + } } @@ -175,28 +165,28 @@ void cBehaviorBreeder::Destroyed() void cBehaviorBreeder::OnRightClicked(cPlayer & a_Player) { - // If a player holding breeding items right-clicked me, go into love mode - if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby()) - { - short HeldItem = a_Player.GetEquippedItem().m_ItemType; - if (m_BreedingItems.ContainsType(HeldItem)) - { - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - } - m_LoveTimer = 20 * 30; // half a minute - m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove); - } - } + // If a player holding breeding items right-clicked me, go into love mode + if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby()) + { + short HeldItem = a_Player.GetEquippedItem().m_ItemType; + if (m_BreedingItems.ContainsType(HeldItem)) + { + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + m_LoveTimer = 20 * 30; // half a minute + m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove); + } + } } void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner) { - m_LovePartner = a_Partner; - m_MatingTimer = 50; // about 3 seconds of mating + m_LovePartner = a_Partner; + m_MatingTimer = 50; // about 3 seconds of mating } @@ -205,13 +195,13 @@ void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner) void cBehaviorBreeder::ResetLoveMode() { - m_LovePartner = nullptr; - m_LoveTimer = 0; - m_MatingTimer = 0; - m_LoveCooldown = 20 * 60 * 5; // 5 minutes + m_LovePartner = nullptr; + m_LoveTimer = 0; + m_MatingTimer = 0; + m_LoveCooldown = 20 * 60 * 5; // 5 minutes - // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata - m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); + // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata + m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); } @@ -220,7 +210,7 @@ void cBehaviorBreeder::ResetLoveMode() bool cBehaviorBreeder::IsInLove() const { - return m_LoveTimer > 0; + return m_LoveTimer > 0; } @@ -229,5 +219,5 @@ bool cBehaviorBreeder::IsInLove() const bool cBehaviorBreeder::IsInLoveCooldown() const { - return (m_LoveCooldown > 0); + return (m_LoveCooldown > 0); } diff --git a/src/Mobs/Behaviors/BehaviorBreeder.h b/src/Mobs/Behaviors/BehaviorBreeder.h index 4d7dc1aa4..fa52a40d4 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.h +++ b/src/Mobs/Behaviors/BehaviorBreeder.h @@ -17,44 +17,42 @@ class cBehaviorBreeder { public: - cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems); + cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems); - // Functions our host Monster should invoke: - void Tick(); - bool ActiveTick(); - void OnRightClicked(cPlayer & a_Player); - void Destroyed(); + // Functions our host Monster should invoke: + void Tick(); + bool ActiveTick(); + void OnRightClicked(cPlayer & a_Player); + void Destroyed(); - /** Returns the partner which the monster is currently mating with. */ - cMonster * GetPartner(void) const { return m_LovePartner; } + /** Returns the partner which the monster is currently mating with. */ + cMonster * GetPartner(void) const { return m_LovePartner; } - /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */ - void EngageLoveMode(cMonster * a_Partner); + /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */ + void EngageLoveMode(cMonster * a_Partner); - /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */ - void ResetLoveMode(); + /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */ + void ResetLoveMode(); - /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */ - bool IsInLove() const; + /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */ + bool IsInLove() const; - /** Returns whether the monster is tired of breeding and is in the cooldown state. */ - bool IsInLoveCooldown() const; + /** Returns whether the monster is tired of breeding and is in the cooldown state. */ + bool IsInLoveCooldown() const; private: - /** Our parent */ - cMonster * m_Parent; + /** Our parent */ + cMonster * m_Parent; - /** The monster's breeding partner. */ - cMonster * m_LovePartner; + /** The monster's breeding partner. */ + cMonster * m_LovePartner; - /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */ - int m_LoveTimer; + /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */ + int m_LoveTimer; - /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */ - int m_LoveCooldown; + /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */ + int m_LoveCooldown; - /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */ - int m_MatingTimer; - - cItems & m_BreedingItems; + /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */ + int m_MatingTimer; }; diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.cpp b/src/Mobs/Behaviors/BehaviorItemFollower.cpp index 89e25ed57..275cb8c24 100644 --- a/src/Mobs/Behaviors/BehaviorItemFollower.cpp +++ b/src/Mobs/Behaviors/BehaviorItemFollower.cpp @@ -21,7 +21,7 @@ bool cBehaviorItemFollower::ActiveTick() { cWorld * World = m_Parent->GetWorld(); cItems FollowedItems; - m_ParentInterface->GetFollowedItems(FollowedItems); + m_Parent->GetFollowedItems(FollowedItems); if (FollowedItems.Size() > 0) { cPlayer * a_Closest_Player = m_Parent->GetNearestPlayer(); diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.h b/src/Mobs/Behaviors/BehaviorItemFollower.h index 2abdeb381..28f00c473 100644 --- a/src/Mobs/Behaviors/BehaviorItemFollower.h +++ b/src/Mobs/Behaviors/BehaviorItemFollower.h @@ -3,20 +3,16 @@ // Makes the mob follow specific held items class cBehaviorItemFollower; -class iBehaviorItemFollower; - //fwds class cMonster; class cItems; - - - - class cBehaviorItemFollower { public: - cBehaviorItemFollower(cMonster * a_Parent); + cBehaviorItemFollower(cMonster * a_Parent, cItems & a_Items); + + void GetBreedingItems(cItems & a_Items); // Functions our host Monster should invoke: bool ActiveTick(); diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index 7ada21369..e9126ff2d 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -9,7 +9,7 @@ cBlaze::cBlaze(void) : - super("Blaze", mtBlaze, "entity.blaze.hurt", "entity.blaze.death", 0.6, 1.8) + super("Blaze", mtBlaze, "entity.blaze.hurt", "entity.blaze.death", 0.6, 1.8, 15) { SetGravity(-8.0f); SetAirDrag(0.05f); diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp index 8d8e15d85..78e04f7e0 100644 --- a/src/Mobs/CaveSpider.cpp +++ b/src/Mobs/CaveSpider.cpp @@ -8,7 +8,7 @@ cCaveSpider::cCaveSpider(void) : - super("CaveSpider", mtCaveSpider, "entity.spider.hurt", "entity.spider.death", 0.7, 0.5) + super("CaveSpider", mtCaveSpider, "entity.spider.hurt", "entity.spider.death", 0.7, 0.5, 15) { } diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index 1068295e6..80cff7fb8 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -5,16 +5,12 @@ - - - - cChicken::cChicken(void) : - super("Chicken", mtChicken, "entity.chicken.hurt", "entity.chicken.death", 0.3, 0.4), - m_EggDropTimer(0) + super("Chicken", mtChicken, "entity.chicken.hurt", "entity.chicken.death", 0.3, 0.4), + m_EggDropTimer(0) { - SetGravity(-2.0f); - SetAirDrag(0.0f); + SetGravity(-2.0f); + SetAirDrag(0.0f); } @@ -22,36 +18,36 @@ cChicken::cChicken(void) : void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { - super::Tick(a_Dt, a_Chunk); - if (!IsTicking()) - { - // The base class tick destroyed us - return; - } - - if (IsBaby()) - { - return; // Babies don't lay eggs - } - - if ((m_EggDropTimer == 6000) && GetRandomProvider().RandBool()) - { - cItems Drops; - m_EggDropTimer = 0; - Drops.push_back(cItem(E_ITEM_EGG, 1)); - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); - } - else if (m_EggDropTimer == 12000) - { - cItems Drops; - m_EggDropTimer = 0; - Drops.push_back(cItem(E_ITEM_EGG, 1)); - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); - } - else - { - m_EggDropTimer++; - } + super::Tick(a_Dt, a_Chunk); + if (!IsTicking()) + { + // The base class tick destroyed us + return; + } + + if (IsBaby()) + { + return; // Babies don't lay eggs + } + + if ((m_EggDropTimer == 6000) && GetRandomProvider().RandBool()) + { + cItems Drops; + m_EggDropTimer = 0; + Drops.push_back(cItem(E_ITEM_EGG, 1)); + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); + } + else if (m_EggDropTimer == 12000) + { + cItems Drops; + m_EggDropTimer = 0; + Drops.push_back(cItem(E_ITEM_EGG, 1)); + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); + } + else + { + m_EggDropTimer++; + } } @@ -60,13 +56,13 @@ void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_FEATHER); - AddRandomDropItem(a_Drops, 1, 1, IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN); + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_FEATHER); + AddRandomDropItem(a_Drops, 1, 1, IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN); } @@ -75,7 +71,7 @@ void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cChicken::HandleFalling(void) { - // empty - chickens don't take fall damage + // empty - chickens don't take fall damage } diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h index 3be338b15..b954c19ec 100644 --- a/src/Mobs/Chicken.h +++ b/src/Mobs/Chicken.h @@ -7,28 +7,28 @@ class cChicken : - public cPassiveMonster + public cPassiveMonster { - typedef cPassiveMonster super; + typedef cPassiveMonster super; public: - cChicken(void); + cChicken(void); - CLASS_PROTODEF(cChicken) + CLASS_PROTODEF(cChicken) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void GetFollowedItems(cItems & a_Items) override - { - a_Items.Add(E_ITEM_SEEDS); - } + virtual void GetFollowedItems(cItems & a_Items) override + { + a_Items.Add(E_ITEM_SEEDS); + } - virtual void HandleFalling(void) override; + virtual void HandleFalling(void) override; private: - int m_EggDropTimer; + int m_EggDropTimer; } ; diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 9736fe440..c92f2369f 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -6,12 +6,8 @@ - - - - cCow::cCow(void) : - super("Cow", mtCow, "entity.cow.hurt", "entity.cow.death", 0.9, 1.3) + super("Cow", mtCow, "entity.cow.hurt", "entity.cow.death", 0.9, 1.3) { } @@ -21,13 +17,13 @@ cCow::cCow(void) : void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER); - AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER); + AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); } @@ -36,15 +32,15 @@ void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cCow::OnRightClicked(cPlayer & a_Player) { - super::OnRightClicked(a_Player); - - short HeldItem = a_Player.GetEquippedItem().m_ItemType; - if (HeldItem == E_ITEM_BUCKET) - { - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - a_Player.GetInventory().AddItem(E_ITEM_MILK); - } - } + super::OnRightClicked(a_Player); + + short HeldItem = a_Player.GetEquippedItem().m_ItemType; + if (HeldItem == E_ITEM_BUCKET) + { + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + a_Player.GetInventory().AddItem(E_ITEM_MILK); + } + } } diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h index 569c6e619..7b3cdb56e 100644 --- a/src/Mobs/Cow.h +++ b/src/Mobs/Cow.h @@ -8,22 +8,22 @@ class cCow : - public cPassiveMonster + public cPassiveMonster { - typedef cPassiveMonster super; + typedef cPassiveMonster super; public: - cCow(); + cCow(); - CLASS_PROTODEF(cCow) + CLASS_PROTODEF(cCow) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void GetFollowedItems(cItems & a_Items) override - { - a_Items.Add(E_ITEM_WHEAT); - } + virtual void GetFollowedItems(cItems & a_Items) override + { + a_Items.Add(E_ITEM_WHEAT); + } } ; diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 505e637b0..f84a8acd7 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -125,6 +125,7 @@ bool cCreeper::DoTakeDamage(TakeDamageInfo & a_TDI) +// mobTODO /* bool cCreeper::Attack(std::chrono::milliseconds a_Dt) { diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index aea36def3..2ef72650b 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -8,29 +8,28 @@ class cCreeper : - public cAggressiveMonster + public cAggressiveMonster { - typedef cAggressiveMonster super; + typedef cAggressiveMonster super; public: - cCreeper(void); + cCreeper(void); - CLASS_PROTODEF(cCreeper) + CLASS_PROTODEF(cCreeper) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; - virtual bool Attack(std::chrono::milliseconds a_Dt) override; - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + virtual void OnRightClicked(cPlayer & a_Player) override; - bool IsBlowing(void) const {return m_bIsBlowing; } - bool IsCharged(void) const {return m_bIsCharged; } - bool IsBurnedWithFlintAndSteel(void) const {return m_BurnedWithFlintAndSteel; } + bool IsBlowing(void) const {return m_bIsBlowing; } + bool IsCharged(void) const {return m_bIsCharged; } + bool IsBurnedWithFlintAndSteel(void) const {return m_BurnedWithFlintAndSteel; } private: - bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel; - int m_ExplodingTimer; + bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel; + int m_ExplodingTimer; } ; diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index 2488e63b1..97a27be5a 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -9,7 +9,7 @@ cGhast::cGhast(void) : - super("Ghast", mtGhast, "entity.ghast.hurt", "entity.ghast.death", 4, 4) + super("Ghast", mtGhast, "entity.ghast.hurt", "entity.ghast.death", 4, 4) { } @@ -19,39 +19,39 @@ cGhast::cGhast(void) : void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER); - AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_GHAST_TEAR); + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER); + AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_GHAST_TEAR); } - -bool cGhast::Attack(std::chrono::milliseconds a_Dt) +// mobTODO +/*bool cGhast::Attack(std::chrono::milliseconds a_Dt) { - if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0)) - { - // Setting this higher gives us more wiggle room for attackrate - Vector3d Speed = GetLookVector() * 20; - Speed.y = Speed.y + 1; - - auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - auto GhastBallPtr = GhastBall.get(); - if (!GhastBallPtr->Initialize(std::move(GhastBall), *m_World)) - { - return false; - } - - ResetAttackCooldown(); - return true; - } - return false; -} + if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0)) + { + // Setting this higher gives us more wiggle room for attackrate + Vector3d Speed = GetLookVector() * 20; + Speed.y = Speed.y + 1; + + auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + auto GhastBallPtr = GhastBall.get(); + if (!GhastBallPtr->Initialize(std::move(GhastBall), *m_World)) + { + return false; + } + + ResetAttackCooldown(); + return true; + } + return false; +}*/ diff --git a/src/Mobs/Ghast.h b/src/Mobs/Ghast.h index a41a72ddc..c3423590a 100644 --- a/src/Mobs/Ghast.h +++ b/src/Mobs/Ghast.h @@ -8,19 +8,18 @@ class cGhast : - public cAggressiveMonster + public cAggressiveMonster { - typedef cAggressiveMonster super; + typedef cAggressiveMonster super; public: - cGhast(void); + cGhast(void); - CLASS_PROTODEF(cGhast) + CLASS_PROTODEF(cGhast) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual bool Attack(std::chrono::milliseconds a_Dt) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - bool IsCharging(void) const {return false; } + bool IsCharging(void) const {return false; } } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 059edbcbc..4513ea3f8 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -1167,13 +1167,17 @@ cBehaviorWanderer * cMonster::GetBehaviorWanderer() -void cMonster::InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2) +void cMonster::InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2) { UNUSED(a_Parent1); UNUSED(a_Parent2); return; } + + + + void cMonster::GetFollowedItems(cItems & a_Items) { return; @@ -1183,6 +1187,11 @@ void cMonster::GetFollowedItems(cItems & a_Items) +void cMonster::GetBreedingItems(cItems & a_Items) +{ + return GetFollowedItems(); +} + std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType) { auto & Random = GetRandomProvider(); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 6308b2945..144228fe7 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -11,6 +11,7 @@ class cClientHandle; //Behavior fwds +class cPassiveMonster; class cBehaviorAggressive; class cBehaviorBreeder; class cBehaviorChaser; @@ -226,9 +227,10 @@ public: virtual cBehaviorStriker * GetBehaviorStriker(); virtual cBehaviorWanderer * GetBehaviorWanderer(); - // Polymorphic behavior functions - virtual void InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2); + // Polymorphic behavior functions ("Skin-specific") + virtual void InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2); virtual void GetFollowedItems(cItems & a_Items); + virtual void GetBreedingItems(cItems & a_Items); protected: diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 1c020232a..f8bc62c09 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -9,9 +9,9 @@ -cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItems & a_BreedingItems, cItems & a_FollowedItems) : +cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItem & a_BreedingItems, cItem & a_FollowedItems) : super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height), - m_BehaviorBreeder(this), m_BehaviorItemFollower(this, a_FollowedItems), m_BehaviorCoward(this) + m_BehaviorBreeder(this), m_BehaviorItemFollower(this), m_BehaviorCoward(this) { m_EMPersonality = PASSIVE; } diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h index 012357024..1ab6d27e3 100644 --- a/src/Mobs/PassiveMonster.h +++ b/src/Mobs/PassiveMonster.h @@ -13,7 +13,9 @@ class cPassiveMonster : public cMonster typedef cMonster super; public: - cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItems & a_BreedingItems, cItems & a_FollowedItems); + cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, + const AString & a_SoundHurt, const AString & a_SoundDeath, + double a_Width, double a_Height); virtual ~cPassiveMonster(); virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void OnRightClicked(cPlayer & a_Player) override; diff --git a/src/Mobs/Silverfish.h b/src/Mobs/Silverfish.h index 90ef5ea5d..c5d39a7a4 100644 --- a/src/Mobs/Silverfish.h +++ b/src/Mobs/Silverfish.h @@ -8,17 +8,17 @@ class cSilverfish : - public cAggressiveMonster + public cAggressiveMonster { - typedef cAggressiveMonster super; + typedef cAggressiveMonster super; public: - cSilverfish(void) : - super("Silverfish", mtSilverfish, "entity.silverfish.hurt", "entity.silverfish.death", 0.3, 0.7) - { - } + cSilverfish(void) : + super("Silverfish", mtSilverfish, "entity.silverfish.hurt", "entity.silverfish.death", 0.3, 0.7, 15) + { + } - CLASS_PROTODEF(cSilverfish) + CLASS_PROTODEF(cSilverfish) } ; diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index e48991a06..22ea3e1bc 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -10,10 +10,10 @@ cSkeleton::cSkeleton(bool IsWither) : - super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", 0.6, 1.8), - m_bIsWither(IsWither) + super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", 0.6, 1.8), + m_bIsWither(IsWither) { - SetBurnsInDaylight(true); + SetBurnsInDaylight(true); } @@ -22,54 +22,54 @@ cSkeleton::cSkeleton(bool IsWither) : void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - if (IsWither()) - { - AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_COAL); - cItems RareDrops; - RareDrops.Add(cItem(E_ITEM_HEAD, 1, 1)); - AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel); - } - else - { - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ARROW); - - } - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_BONE); - AddRandomArmorDropItem(a_Drops, LootingLevel); - AddRandomWeaponDropItem(a_Drops, LootingLevel); + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + if (IsWither()) + { + AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_COAL); + cItems RareDrops; + RareDrops.Add(cItem(E_ITEM_HEAD, 1, 1)); + AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel); + } + else + { + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ARROW); + + } + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_BONE); + AddRandomArmorDropItem(a_Drops, LootingLevel); + AddRandomWeaponDropItem(a_Drops, LootingLevel); } - -bool cSkeleton::Attack(std::chrono::milliseconds a_Dt) +//mobTodo +/*bool cSkeleton::Attack(std::chrono::milliseconds a_Dt) { - StopMovingToPosition(); // Todo handle this in a better way, the skeleton does some uneeded recalcs due to inStateChasing - auto & Random = GetRandomProvider(); - if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0)) - { - Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25)); - Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5; - Speed.y += Random.RandInt(-1, 1); - - auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - auto ArrowPtr = Arrow.get(); - if (!ArrowPtr->Initialize(std::move(Arrow), *m_World)) - { - return false; - } - - ResetAttackCooldown(); - return true; - } - return false; -} + StopMovingToPosition(); // Todo handle this in a better way, the skeleton does some uneeded recalcs due to inStateChasing + auto & Random = GetRandomProvider(); + if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0)) + { + Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25)); + Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5; + Speed.y += Random.RandInt(-1, 1); + + auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + auto ArrowPtr = Arrow.get(); + if (!ArrowPtr->Initialize(std::move(Arrow), *m_World)) + { + return false; + } + + ResetAttackCooldown(); + return true; + } + return false; +}*/ @@ -77,8 +77,8 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt) void cSkeleton::SpawnOn(cClientHandle & a_ClientHandle) { - super::SpawnOn(a_ClientHandle); - a_ClientHandle.SendEntityEquipment(*this, 0, cItem(E_ITEM_BOW)); + super::SpawnOn(a_ClientHandle); + a_ClientHandle.SendEntityEquipment(*this, 0, cItem(E_ITEM_BOW)); } diff --git a/src/Mobs/Skeleton.h b/src/Mobs/Skeleton.h index 0316fb9b5..91e094c4c 100644 --- a/src/Mobs/Skeleton.h +++ b/src/Mobs/Skeleton.h @@ -8,26 +8,26 @@ class cSkeleton : - public cAggressiveMonster + public cAggressiveMonster { - typedef cAggressiveMonster super; + typedef cAggressiveMonster super; public: - cSkeleton(bool IsWither); + cSkeleton(bool IsWither); - CLASS_PROTODEF(cSkeleton) + CLASS_PROTODEF(cSkeleton) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual bool Attack(std::chrono::milliseconds a_Dt) override; - virtual void SpawnOn(cClientHandle & a_ClientHandle) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + /*virtual bool Attack(std::chrono::milliseconds a_Dt) override;*/ + virtual void SpawnOn(cClientHandle & a_ClientHandle) override; - virtual bool IsUndead(void) override { return true; } + virtual bool IsUndead(void) override { return true; } - bool IsWither(void) const { return m_bIsWither; } + bool IsWither(void) const { return m_bIsWither; } private: - bool m_bIsWither; + bool m_bIsWither; } ; diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index 291a3a57f..df4c2f6ee 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -10,17 +10,17 @@ cSlime::cSlime(int a_Size) : - super("Slime", - mtSlime, - Printf("entity.%sslime.hurt", GetSizeName(a_Size).c_str()), - Printf("entity.%sslime.death", GetSizeName(a_Size).c_str()), - 0.6 * a_Size, - 0.6 * a_Size - ), - m_Size(a_Size) + super("Slime", + mtSlime, + Printf("entity.%sslime.hurt", GetSizeName(a_Size).c_str()), + Printf("entity.%sslime.death", GetSizeName(a_Size).c_str()), + 0.6 * a_Size, + 0.6 * a_Size + ), + m_Size(a_Size) { - SetMaxHealth(a_Size * a_Size); - SetAttackDamage(a_Size); + SetMaxHealth(a_Size * a_Size); + SetAttackDamage(a_Size); } @@ -29,33 +29,33 @@ cSlime::cSlime(int a_Size) : void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - - // Only slimes with the size 1 can drop slimeballs. - if (m_Size == 1) - { - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_SLIMEBALL); - } + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + + // Only slimes with the size 1 can drop slimeballs. + if (m_Size == 1) + { + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_SLIMEBALL); + } } - -bool cSlime::Attack(std::chrono::milliseconds a_Dt) +//mobTodo +/*bool cSlime::Attack(std::chrono::milliseconds a_Dt) { - if (m_Size > 1) - { - // Only slimes larger than size 1 attack a player. - return super::Attack(a_Dt); - } + if (m_Size > 1) + { + // Only slimes larger than size 1 attack a player. + return super::Attack(a_Dt); + } - return false; -} + return false; +}*/ @@ -63,28 +63,28 @@ bool cSlime::Attack(std::chrono::milliseconds a_Dt) void cSlime::KilledBy(TakeDamageInfo & a_TDI) { - if (GetHealth() > 0) - { - return; - } - - if (m_Size != 1) - { - auto & Random = GetRandomProvider(); - int SpawnAmount = Random.RandInt(2, 4); - - for (int i = 0; i < SpawnAmount; ++i) - { - double AddX = (i % 2 - 0.5) * m_Size / 4.0; - double AddZ = (i / 2 - 0.5) * m_Size / 4.0; - - auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2); - NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ); - NewSlime->SetYaw(Random.RandReal(360.0f)); - m_World->SpawnMobFinalize(std::move(NewSlime)); - } - } - super::KilledBy(a_TDI); + if (GetHealth() > 0) + { + return; + } + + if (m_Size != 1) + { + auto & Random = GetRandomProvider(); + int SpawnAmount = Random.RandInt(2, 4); + + for (int i = 0; i < SpawnAmount; ++i) + { + double AddX = (i % 2 - 0.5) * m_Size / 4.0; + double AddZ = (i / 2 - 0.5) * m_Size / 4.0; + + auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2); + NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ); + NewSlime->SetYaw(Random.RandReal(360.0f)); + m_World->SpawnMobFinalize(std::move(NewSlime)); + } + } + super::KilledBy(a_TDI); } @@ -93,11 +93,11 @@ void cSlime::KilledBy(TakeDamageInfo & a_TDI) AString cSlime::GetSizeName(int a_Size) { - if (a_Size == 1) - { - return "small_"; - } - return ""; + if (a_Size == 1) + { + return "small_"; + } + return ""; } diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h index c78461a02..26bc6716d 100644 --- a/src/Mobs/Slime.h +++ b/src/Mobs/Slime.h @@ -8,32 +8,32 @@ class cSlime : - public cAggressiveMonster + public cAggressiveMonster { - typedef cAggressiveMonster super; + typedef cAggressiveMonster super; public: - /** Creates a slime of the specified size; size can be 1, 2 or 4, with 1 is the smallest and 4 is the tallest. */ - cSlime(int a_Size); + /** Creates a slime of the specified size; size can be 1, 2 or 4, with 1 is the smallest and 4 is the tallest. */ + cSlime(int a_Size); - CLASS_PROTODEF(cSlime) + CLASS_PROTODEF(cSlime) - // cAggressiveMonster overrides: - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; - virtual bool Attack(std::chrono::milliseconds a_Dt) override; - virtual void KilledBy(TakeDamageInfo & a_TDI) override; + // cAggressiveMonster overrides: + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + // virtual bool Attack(std::chrono::milliseconds a_Dt) override; + virtual void KilledBy(TakeDamageInfo & a_TDI) override; - int GetSize(void) const { return m_Size; } + int GetSize(void) const { return m_Size; } - /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. - Returns either "big" or "small". */ - static AString GetSizeName(int a_Size); + /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. + Returns either "big" or "small". */ + static AString GetSizeName(int a_Size); protected: - /** Size of the slime, with 1 being the smallest. - Vanilla uses sizes 1, 2 and 4 only. */ - int m_Size; + /** Size of the slime, with 1 being the smallest. + Vanilla uses sizes 1, 2 and 4 only. */ + int m_Size; } ; diff --git a/src/Mobs/Spider.cpp b/src/Mobs/Spider.cpp index 971ff22f6..89bd04ff5 100644 --- a/src/Mobs/Spider.cpp +++ b/src/Mobs/Spider.cpp @@ -9,7 +9,7 @@ cSpider::cSpider(void) : - super("Spider", mtSpider, "entity.spider.hurt", "entity.spider.death", 1.4, 0.9) + super("Spider", mtSpider, "entity.spider.hurt", "entity.spider.death", 1.4, 0.9, 11) { } @@ -19,16 +19,16 @@ cSpider::cSpider(void) : void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - unsigned int LootingLevel = 0; - if (a_Killer != nullptr) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING); - if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) - { - AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE); - } + unsigned int LootingLevel = 0; + if (a_Killer != nullptr) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING); + if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) + { + AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE); + } } @@ -37,24 +37,24 @@ void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSpider::EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk) { - if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ())) - { - return; - } - - PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk); - if (!RelSuccess) - { - return; - } - - if ( - a_Player->CanMobsTarget() && - !((Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) > 11) || (Chunk->GetBlockLight(Rel.x, Rel.y, Rel.z) > 11)) - ) - { - super::EventSeePlayer(a_Player, a_Chunk); - } + if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ())) + { + return; + } + + PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk); + if (!RelSuccess) + { + return; + } + + if ( + a_Player->CanMobsTarget() && + !((Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) > 11) || (Chunk->GetBlockLight(Rel.x, Rel.y, Rel.z) > 11)) + ) + { + super::EventSeePlayer(a_Player, a_Chunk); + } } @@ -63,21 +63,21 @@ void cSpider::EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk) bool cSpider::DoTakeDamage(TakeDamageInfo & a_TDI) { - if (!super::DoTakeDamage(a_TDI)) - { - return false; - } - - // If the source of the damage is not from an pawn entity, switch to idle - if ((a_TDI.Attacker == nullptr) || !a_TDI.Attacker->IsPawn()) - { - m_EMState = IDLE; - } - else - { - // If the source of the damage is from a pawn entity, chase that entity - m_EMState = CHASING; - } - - return true; + if (!super::DoTakeDamage(a_TDI)) + { + return false; + } + + // If the source of the damage is not from an pawn entity, switch to idle + if ((a_TDI.Attacker == nullptr) || !a_TDI.Attacker->IsPawn()) + { + m_EMState = IDLE; + } + else + { + // If the source of the damage is from a pawn entity, chase that entity + m_EMState = CHASING; + } + + return true; } diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 33a9b31ee..520de483d 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -12,16 +12,16 @@ cWolf::cWolf(void) : - super("Wolf", mtWolf, "entity.wolf.hurt", "entity.wolf.death", 0.6, 0.8), - m_IsSitting(false), - m_IsTame(false), - m_IsBegging(false), - m_IsAngry(false), - m_OwnerName(""), - m_CollarColor(E_META_DYE_ORANGE), - m_NotificationCooldown(0) + super("Wolf", mtWolf, "entity.wolf.hurt", "entity.wolf.death", 0.6, 0.8), + m_IsSitting(false), + m_IsTame(false), + m_IsBegging(false), + m_IsAngry(false), + m_OwnerName(""), + m_CollarColor(E_META_DYE_ORANGE), + m_NotificationCooldown(0) { - m_RelativeWalkSpeed = 2; + m_RelativeWalkSpeed = 2; } @@ -30,43 +30,43 @@ cWolf::cWolf(void) : bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI) { - cPawn * PreviousTarget = GetTarget(); - if (!super::DoTakeDamage(a_TDI)) - { - return false; - } - - if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPawn()) - { - auto currTarget = GetTarget(); - if ((currTarget != nullptr) && currTarget->IsPlayer()) - { - if (m_IsTame) - { - if ((static_cast<cPlayer*>(currTarget)->GetUUID() == m_OwnerUUID)) - { - SetTarget(PreviousTarget); // Do not attack owner - } - else - { - SetIsSitting(false); - NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker)); - } - } - else - { - m_IsAngry = true; - } - } - else if (m_IsTame) - { - SetIsSitting(false); - NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker)); - } - } - - m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face - return true; + cPawn * PreviousTarget = GetTarget(); + if (!super::DoTakeDamage(a_TDI)) + { + return false; + } + + if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPawn()) + { + auto currTarget = GetTarget(); + if ((currTarget != nullptr) && currTarget->IsPlayer()) + { + if (m_IsTame) + { + if ((static_cast<cPlayer*>(currTarget)->GetUUID() == m_OwnerUUID)) + { + SetTarget(PreviousTarget); // Do not attack owner + } + else + { + SetIsSitting(false); + NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker)); + } + } + else + { + m_IsAngry = true; + } + } + else if (m_IsTame) + { + SetIsSitting(false); + NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker)); + } + } + + m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face + return true; } @@ -75,43 +75,43 @@ bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI) void cWolf::NotifyAlliesOfFight(cPawn * a_Opponent) { - if (GetOwnerName() == "") - { - return; - } - m_NotificationCooldown = 15; - class cCallback : public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - a_Player->NotifyNearbyWolves(m_Opponent, false); - return false; - } - public: - cPawn * m_Opponent; - } Callback; - - Callback.m_Opponent = a_Opponent; - m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback); + if (GetOwnerName() == "") + { + return; + } + m_NotificationCooldown = 15; + class cCallback : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + a_Player->NotifyNearbyWolves(m_Opponent, false); + return false; + } + public: + cPawn * m_Opponent; + } Callback; + + Callback.m_Opponent = a_Opponent; + m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback); } -bool cWolf::Attack(std::chrono::milliseconds a_Dt) +/*bool cWolf::Attack(std::chrono::milliseconds a_Dt) { - UNUSED(a_Dt); + UNUSED(a_Dt); - if ((GetTarget() != nullptr) && (GetTarget()->IsPlayer())) - { - if (static_cast<cPlayer *>(GetTarget())->GetUUID() == m_OwnerUUID) - { - SetTarget(nullptr); - return false; - } - } + if ((GetTarget() != nullptr) && (GetTarget()->IsPlayer())) + { + if (static_cast<cPlayer *>(GetTarget())->GetUUID() == m_OwnerUUID) + { + SetTarget(nullptr); + return false; + } + } - NotifyAlliesOfFight(static_cast<cPawn*>(GetTarget())); - return super::Attack(a_Dt); + NotifyAlliesOfFight(static_cast<cPawn*>(GetTarget())); + return super::Attack(a_Dt); -} +}*/ @@ -119,46 +119,46 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt) void cWolf::ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved) { - if ( - (a_Opponent == nullptr) || IsSitting() || (!IsTame()) || - (!a_Opponent->IsPawn()) || (a_PlayerID != m_OwnerUUID) - ) - { - return; - } - - // If we already have a target - if (GetTarget() != nullptr) - { - // If a wolf is asking for help and we already have a target, do nothing - if (!a_IsPlayerInvolved) - { - return; - } - // If a player is asking for help and we already have a target, - // there's a 50% chance of helping and a 50% chance of doing nothing - // This helps spread a wolf pack's targets over several mobs - else if (GetRandomProvider().RandBool()) - { - return; - } - } - - if (a_Opponent->IsPlayer() && static_cast<cPlayer *>(a_Opponent)->GetUUID() == m_OwnerUUID) - { - return; // Our owner has hurt himself, avoid attacking them. - } - - if (a_Opponent->IsMob() && static_cast<cMonster *>(a_Opponent)->GetMobType() == mtWolf) - { - cWolf * Wolf = static_cast<cWolf *>(a_Opponent); - if (Wolf->GetOwnerUUID() == GetOwnerUUID()) - { - return; // Our owner attacked one of their wolves. Abort attacking wolf. - } - } - - SetTarget(a_Opponent); + if ( + (a_Opponent == nullptr) || IsSitting() || (!IsTame()) || + (!a_Opponent->IsPawn()) || (a_PlayerID != m_OwnerUUID) + ) + { + return; + } + + // If we already have a target + if (GetTarget() != nullptr) + { + // If a wolf is asking for help and we already have a target, do nothing + if (!a_IsPlayerInvolved) + { + return; + } + // If a player is asking for help and we already have a target, + // there's a 50% chance of helping and a 50% chance of doing nothing + // This helps spread a wolf pack's targets over several mobs + else if (GetRandomProvider().RandBool()) + { + return; + } + } + + if (a_Opponent->IsPlayer() && static_cast<cPlayer *>(a_Opponent)->GetUUID() == m_OwnerUUID) + { + return; // Our owner has hurt himself, avoid attacking them. + } + + if (a_Opponent->IsMob() && static_cast<cMonster *>(a_Opponent)->GetMobType() == mtWolf) + { + cWolf * Wolf = static_cast<cWolf *>(a_Opponent); + if (Wolf->GetOwnerUUID() == GetOwnerUUID()) + { + return; // Our owner attacked one of their wolves. Abort attacking wolf. + } + } + + SetTarget(a_Opponent); } @@ -169,82 +169,82 @@ void cWolf::ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool void cWolf::OnRightClicked(cPlayer & a_Player) { - const cItem & EquippedItem = a_Player.GetEquippedItem(); - const int EquippedItemType = EquippedItem.m_ItemType; - - if (!IsTame() && !IsAngry()) - { - // If the player is holding a bone, try to tame the wolf: - if (EquippedItemType == E_ITEM_BONE) - { - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - } - - if (GetRandomProvider().RandBool(0.125)) - { - // Taming succeeded - SetMaxHealth(20); - SetIsTame(true); - SetOwner(a_Player.GetName(), a_Player.GetUUID()); - m_World->BroadcastEntityStatus(*this, esWolfTamed); - m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); - } - else - { - // Taming failed - m_World->BroadcastEntityStatus(*this, esWolfTaming); - m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); - } - } - } - else if (IsTame()) - { - // Feed the wolf, restoring its health, or dye its collar: - switch (EquippedItemType) - { - case E_ITEM_RAW_BEEF: - case E_ITEM_STEAK: - case E_ITEM_RAW_PORKCHOP: - case E_ITEM_COOKED_PORKCHOP: - case E_ITEM_RAW_CHICKEN: - case E_ITEM_COOKED_CHICKEN: - case E_ITEM_ROTTEN_FLESH: - { - if (m_Health < m_MaxHealth) - { - Heal(ItemHandler(EquippedItemType)->GetFoodInfo(&EquippedItem).FoodLevel); - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - } - } - break; - } - case E_ITEM_DYE: - { - if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? - { - SetCollarColor(EquippedItem.m_ItemDamage); - if (!a_Player.IsGameModeCreative()) - { - a_Player.GetInventory().RemoveOneEquippedItem(); - } - } - break; - } - default: - { - if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? - { - SetIsSitting(!IsSitting()); - } - } - } - } - - m_World->BroadcastEntityMetadata(*this); + const cItem & EquippedItem = a_Player.GetEquippedItem(); + const int EquippedItemType = EquippedItem.m_ItemType; + + if (!IsTame() && !IsAngry()) + { + // If the player is holding a bone, try to tame the wolf: + if (EquippedItemType == E_ITEM_BONE) + { + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + + if (GetRandomProvider().RandBool(0.125)) + { + // Taming succeeded + SetMaxHealth(20); + SetIsTame(true); + SetOwner(a_Player.GetName(), a_Player.GetUUID()); + m_World->BroadcastEntityStatus(*this, esWolfTamed); + m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); + } + else + { + // Taming failed + m_World->BroadcastEntityStatus(*this, esWolfTaming); + m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5); + } + } + } + else if (IsTame()) + { + // Feed the wolf, restoring its health, or dye its collar: + switch (EquippedItemType) + { + case E_ITEM_RAW_BEEF: + case E_ITEM_STEAK: + case E_ITEM_RAW_PORKCHOP: + case E_ITEM_COOKED_PORKCHOP: + case E_ITEM_RAW_CHICKEN: + case E_ITEM_COOKED_CHICKEN: + case E_ITEM_ROTTEN_FLESH: + { + if (m_Health < m_MaxHealth) + { + Heal(ItemHandler(EquippedItemType)->GetFoodInfo(&EquippedItem).FoodLevel); + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + } + break; + } + case E_ITEM_DYE: + { + if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? + { + SetCollarColor(EquippedItem.m_ItemDamage); + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + } + break; + } + default: + { + if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog? + { + SetIsSitting(!IsSitting()); + } + } + } + } + + m_World->BroadcastEntityMetadata(*this); } @@ -253,92 +253,92 @@ void cWolf::OnRightClicked(cPlayer & a_Player) void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { - if (!IsAngry()) - { - cMonster::Tick(a_Dt, a_Chunk); - if (m_NotificationCooldown > 0) - { - m_NotificationCooldown -= 1; - } - } - else - { - super::Tick(a_Dt, a_Chunk); - } - - if (!IsTicking()) - { - // The base class tick destroyed us - return; - } - - if (GetTarget() == nullptr) - { - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance)); - if (a_Closest_Player != nullptr) - { - switch (a_Closest_Player->GetEquippedItem().m_ItemType) - { - case E_ITEM_BONE: - case E_ITEM_RAW_BEEF: - case E_ITEM_STEAK: - case E_ITEM_RAW_CHICKEN: - case E_ITEM_COOKED_CHICKEN: - case E_ITEM_ROTTEN_FLESH: - case E_ITEM_RAW_PORKCHOP: - case E_ITEM_COOKED_PORKCHOP: - { - if (!IsBegging()) - { - SetIsBegging(true); - m_World->BroadcastEntityMetadata(*this); - } - - m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food - - // Don't move to the player if the wolf is sitting. - if (!IsSitting()) - { - MoveToPosition(a_Closest_Player->GetPosition()); - } - - break; - } - default: - { - if (IsBegging()) - { - SetIsBegging(false); - m_World->BroadcastEntityMetadata(*this); - } - } - } - } - } - else - { - if (IsSitting()) - { - SetTarget(nullptr); - } - else - { - MoveToPosition(GetTarget()->GetPosition()); - if (TargetIsInRange()) - { - Attack(a_Dt); - } - } - } - - if (IsTame() && !IsSitting()) - { - TickFollowPlayer(); - } - else if (IsSitting()) - { - StopMovingToPosition(); - } + if (!IsAngry()) + { + cMonster::Tick(a_Dt, a_Chunk); + if (m_NotificationCooldown > 0) + { + m_NotificationCooldown -= 1; + } + } + else + { + super::Tick(a_Dt, a_Chunk); + } + + if (!IsTicking()) + { + // The base class tick destroyed us + return; + } + + if (GetTarget() == nullptr) + { + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance)); + if (a_Closest_Player != nullptr) + { + switch (a_Closest_Player->GetEquippedItem().m_ItemType) + { + case E_ITEM_BONE: + case E_ITEM_RAW_BEEF: + case E_ITEM_STEAK: + case E_ITEM_RAW_CHICKEN: + case E_ITEM_COOKED_CHICKEN: + case E_ITEM_ROTTEN_FLESH: + case E_ITEM_RAW_PORKCHOP: + case E_ITEM_COOKED_PORKCHOP: + { + if (!IsBegging()) + { + SetIsBegging(true); + m_World->BroadcastEntityMetadata(*this); + } + + m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food + + // Don't move to the player if the wolf is sitting. + if (!IsSitting()) + { + MoveToPosition(a_Closest_Player->GetPosition()); + } + + break; + } + default: + { + if (IsBegging()) + { + SetIsBegging(false); + m_World->BroadcastEntityMetadata(*this); + } + } + } + } + } + else + { + if (IsSitting()) + { + SetTarget(nullptr); + } + else + { + MoveToPosition(GetTarget()->GetPosition()); + if (TargetIsInRange()) + { + Attack(a_Dt); + } + } + } + + if (IsTame() && !IsSitting()) + { + TickFollowPlayer(); + } + else if (IsSitting()) + { + StopMovingToPosition(); + } } @@ -347,61 +347,61 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cWolf::TickFollowPlayer() { - class cCallback : - public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - OwnerPos = a_Player->GetPosition(); - OwnerFlying = a_Player->IsFlying(); - return true; - } - public: - Vector3d OwnerPos; - bool OwnerFlying; - } Callback; - - if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) - { - // The player is present in the world, follow him: - double Distance = (Callback.OwnerPos - GetPosition()).Length(); - if (Distance > 20) - { - if (!Callback.OwnerFlying) - { - Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); - TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); - SetTarget(nullptr); - } - } - if (Distance < 2) - { - if (GetTarget() == nullptr) - { - StopMovingToPosition(); - } - } - else - { - if (GetTarget() == nullptr) - { - if (!Callback.OwnerFlying) - { - MoveToPosition(Callback.OwnerPos); - } - } - } - } + class cCallback : + public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + OwnerPos = a_Player->GetPosition(); + OwnerFlying = a_Player->IsFlying(); + return true; + } + public: + Vector3d OwnerPos; + bool OwnerFlying; + } Callback; + + if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) + { + // The player is present in the world, follow him: + double Distance = (Callback.OwnerPos - GetPosition()).Length(); + if (Distance > 20) + { + if (!Callback.OwnerFlying) + { + Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); + TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + SetTarget(nullptr); + } + } + if (Distance < 2) + { + if (GetTarget() == nullptr) + { + StopMovingToPosition(); + } + } + else + { + if (GetTarget() == nullptr) + { + if (!Callback.OwnerFlying) + { + MoveToPosition(Callback.OwnerPos); + } + } + } + } } void cWolf::InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { - if (!IsTame()) - { - cMonster::InStateIdle(a_Dt, a_Chunk); - } + if (!IsTame()) + { + cMonster::InStateIdle(a_Dt, a_Chunk); + } } diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index e05fedbf8..f001fb559 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -9,64 +9,64 @@ class cEntity; class cWolf : - public cPassiveAggressiveMonster + public cPassiveAggressiveMonster { - typedef cPassiveAggressiveMonster super; + typedef cPassiveAggressiveMonster super; public: - cWolf(void); - - CLASS_PROTODEF(cWolf) - - void NotifyAlliesOfFight(cPawn * a_Opponent); - virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; - virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void TickFollowPlayer(); - virtual bool Attack(std::chrono::milliseconds a_Dt) override; - - // Get functions - bool IsSitting (void) const override { return m_IsSitting; } - bool IsTame (void) const override { return m_IsTame; } - bool IsBegging (void) const { return m_IsBegging; } - bool IsAngry (void) const { return m_IsAngry; } - AString GetOwnerName (void) const { return m_OwnerName; } - AString GetOwnerUUID (void) const { return m_OwnerUUID; } - int GetCollarColor(void) const { return m_CollarColor; } - - // Set functions - void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; } - void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; } - void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; } - void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; } - void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; } - void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID) - { - m_OwnerName = a_NewOwnerName; - m_OwnerUUID = a_NewOwnerUUID; - } - - /** Notfies the wolf of a nearby fight. - The wolf may then decide to attack a_Opponent. - If a_IsPlayer is true, then the player whose ID is a_PlayerID is fighting a_Opponent - If false, then a wolf owned by the player whose ID is a_PlayerID is fighting a_Opponent - @param a_PlayerID The ID of the fighting player, or the ID of the owner whose wolf is fighting. - @param a_Opponent The opponent who is being faught. - @param a_IsPlayerInvolved Whether the fighter a player or a wolf. */ - void ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved); - - virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + cWolf(void); + + CLASS_PROTODEF(cWolf) + + void NotifyAlliesOfFight(cPawn * a_Opponent); + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + virtual void TickFollowPlayer(); + //virtual bool Attack(std::chrono::milliseconds a_Dt) override; + + // Get functions + bool IsSitting (void) const override { return m_IsSitting; } + bool IsTame (void) const override { return m_IsTame; } + bool IsBegging (void) const { return m_IsBegging; } + bool IsAngry (void) const { return m_IsAngry; } + AString GetOwnerName (void) const { return m_OwnerName; } + AString GetOwnerUUID (void) const { return m_OwnerUUID; } + int GetCollarColor(void) const { return m_CollarColor; } + + // Set functions + void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; } + void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; } + void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; } + void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; } + void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; } + void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID) + { + m_OwnerName = a_NewOwnerName; + m_OwnerUUID = a_NewOwnerUUID; + } + + /** Notfies the wolf of a nearby fight. + The wolf may then decide to attack a_Opponent. + If a_IsPlayer is true, then the player whose ID is a_PlayerID is fighting a_Opponent + If false, then a wolf owned by the player whose ID is a_PlayerID is fighting a_Opponent + @param a_PlayerID The ID of the fighting player, or the ID of the owner whose wolf is fighting. + @param a_Opponent The opponent who is being faught. + @param a_IsPlayerInvolved Whether the fighter a player or a wolf. */ + void ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved); + + virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; protected: - bool m_IsSitting; - bool m_IsTame; - bool m_IsBegging; - bool m_IsAngry; - AString m_OwnerName; - AString m_OwnerUUID; - int m_CollarColor; - int m_NotificationCooldown; + bool m_IsSitting; + bool m_IsTame; + bool m_IsBegging; + bool m_IsAngry; + AString m_OwnerName; + AString m_OwnerUUID; + int m_CollarColor; + int m_NotificationCooldown; } ; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index f278437ff..68d5c3f9d 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -3,8 +3,8 @@ /* Implements the 1.8 protocol classes: - - cProtocol_1_8_0 - - release 1.8 protocol (#47) + - cProtocol_1_8_0 + - release 1.8 protocol (#47) */ #include "Globals.h" @@ -58,26 +58,26 @@ static const Int16 SLOT_NUM_OUTSIDE = -999; #define HANDLE_READ(ByteBuf, Proc, Type, Var) \ - Type Var; \ - if (!ByteBuf.Proc(Var))\ - {\ - return;\ - } + Type Var; \ + if (!ByteBuf.Proc(Var))\ + {\ + return;\ + } #define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \ - Type Var; \ - { \ - if (!ByteBuf.Proc(Var)) \ - { \ - ByteBuf.CheckValid(); \ - return false; \ - } \ - ByteBuf.CheckValid(); \ - } + Type Var; \ + { \ + if (!ByteBuf.Proc(Var)) \ + { \ + ByteBuf.CheckValid(); \ + return false; \ + } \ + ByteBuf.CheckValid(); \ + } @@ -101,44 +101,44 @@ extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; // cProtocol_1_8_0: cProtocol_1_8_0::cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client), - m_ServerAddress(a_ServerAddress), - m_ServerPort(a_ServerPort), - m_State(a_State), - m_ReceivedData(32 KiB), - m_IsEncrypted(false) -{ - - // BungeeCord handling: - // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: - // hostname\00ip-address\00uuid\00profile-properties-as-json - AStringVector Params; - if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) - { - LOGD("Player at %s connected via BungeeCord", Params[1].c_str()); - m_ServerAddress = Params[0]; - m_Client->SetIPString(Params[1]); - m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); - m_Client->SetProperties(Params[3]); - } - - // Create the comm log file, if so requested: - if (g_ShouldLogCommIn || g_ShouldLogCommOut) - { - static int sCounter = 0; - cFile::CreateFolder("CommLogs"); - AString IP(a_Client->GetIPString()); - ReplaceString(IP, ":", "_"); - AString FileName = Printf("CommLogs/%x_%d__%s.log", - static_cast<unsigned>(time(nullptr)), - sCounter++, - IP.c_str() - ); - if (!m_CommLogFile.Open(FileName, cFile::fmWrite)) - { - LOG("Cannot log communication to file, the log file \"%s\" cannot be opened for writing.", FileName.c_str()); - } - } + super(a_Client), + m_ServerAddress(a_ServerAddress), + m_ServerPort(a_ServerPort), + m_State(a_State), + m_ReceivedData(32 KiB), + m_IsEncrypted(false) +{ + + // BungeeCord handling: + // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: + // hostname\00ip-address\00uuid\00profile-properties-as-json + AStringVector Params; + if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) + { + LOGD("Player at %s connected via BungeeCord", Params[1].c_str()); + m_ServerAddress = Params[0]; + m_Client->SetIPString(Params[1]); + m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); + m_Client->SetProperties(Params[3]); + } + + // Create the comm log file, if so requested: + if (g_ShouldLogCommIn || g_ShouldLogCommOut) + { + static int sCounter = 0; + cFile::CreateFolder("CommLogs"); + AString IP(a_Client->GetIPString()); + ReplaceString(IP, ":", "_"); + AString FileName = Printf("CommLogs/%x_%d__%s.log", + static_cast<unsigned>(time(nullptr)), + sCounter++, + IP.c_str() + ); + if (!m_CommLogFile.Open(FileName, cFile::fmWrite)) + { + LOG("Cannot log communication to file, the log file \"%s\" cannot be opened for writing.", FileName.c_str()); + } + } } @@ -147,22 +147,22 @@ cProtocol_1_8_0::cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_Ser void cProtocol_1_8_0::DataReceived(const char * a_Data, size_t a_Size) { - if (m_IsEncrypted) - { - Byte Decrypted[512]; - while (a_Size > 0) - { - size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; - m_Decryptor.ProcessData(Decrypted, reinterpret_cast<const Byte *>(a_Data), NumBytes); - AddReceivedData(reinterpret_cast<const char *>(Decrypted), NumBytes); - a_Size -= NumBytes; - a_Data += NumBytes; - } - } - else - { - AddReceivedData(a_Data, a_Size); - } + if (m_IsEncrypted) + { + Byte Decrypted[512]; + while (a_Size > 0) + { + size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; + m_Decryptor.ProcessData(Decrypted, reinterpret_cast<const Byte *>(a_Data), NumBytes); + AddReceivedData(reinterpret_cast<const char *>(Decrypted), NumBytes); + a_Size -= NumBytes; + a_Data += NumBytes; + } + } + else + { + AddReceivedData(a_Data, a_Size); + } } @@ -171,12 +171,12 @@ void cProtocol_1_8_0::DataReceived(const char * a_Data, size_t a_Size) void cProtocol_1_8_0::SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1b); // Attach Entity packet - Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt32(a_Vehicle.GetUniqueID()); - Pkt.WriteBool(false); + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet + Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt32(a_Vehicle.GetUniqueID()); + Pkt.WriteBool(false); } @@ -185,13 +185,13 @@ void cProtocol_1_8_0::SendAttachEntity(const cEntity & a_Entity, const cEntity & void cProtocol_1_8_0::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x24); // Block Action packet - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); - Pkt.WriteBEInt8(a_Byte1); - Pkt.WriteBEInt8(a_Byte2); - Pkt.WriteVarInt32(a_BlockType); + cPacketizer Pkt(*this, 0x24); // Block Action packet + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteBEInt8(a_Byte1); + Pkt.WriteBEInt8(a_Byte2); + Pkt.WriteVarInt32(a_BlockType); } @@ -200,12 +200,12 @@ void cProtocol_1_8_0::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, void cProtocol_1_8_0::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x25); // Block Break Animation packet - Pkt.WriteVarInt32(a_EntityID); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); - Pkt.WriteBEInt8(a_Stage); + cPacketizer Pkt(*this, 0x25); // Block Break Animation packet + Pkt.WriteVarInt32(a_EntityID); + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteBEInt8(a_Stage); } @@ -214,11 +214,11 @@ void cProtocol_1_8_0::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_ void cProtocol_1_8_0::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x23); // Block Change packet - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); - Pkt.WriteVarInt32((static_cast<UInt32>(a_BlockType) << 4) | (static_cast<UInt32>(a_BlockMeta) & 15)); + cPacketizer Pkt(*this, 0x23); // Block Change packet + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteVarInt32((static_cast<UInt32>(a_BlockType) << 4) | (static_cast<UInt32>(a_BlockMeta) & 15)); } @@ -227,18 +227,18 @@ void cProtocol_1_8_0::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, void cProtocol_1_8_0::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x22); // Multi Block Change packet - Pkt.WriteBEInt32(a_ChunkX); - Pkt.WriteBEInt32(a_ChunkZ); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Changes.size())); - for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) - { - Int16 Coords = static_cast<Int16>(itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12)); - Pkt.WriteBEInt16(Coords); - Pkt.WriteVarInt32(static_cast<UInt32>(itr->m_BlockType & 0xFFF) << 4 | (itr->m_BlockMeta & 0xF)); - } // for itr - a_Changes[] + cPacketizer Pkt(*this, 0x22); // Multi Block Change packet + Pkt.WriteBEInt32(a_ChunkX); + Pkt.WriteBEInt32(a_ChunkZ); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Changes.size())); + for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) + { + Int16 Coords = static_cast<Int16>(itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12)); + Pkt.WriteBEInt16(Coords); + Pkt.WriteVarInt32(static_cast<UInt32>(itr->m_BlockType & 0xFFF) << 4 | (itr->m_BlockMeta & 0xF)); + } // for itr - a_Changes[] } @@ -247,8 +247,8 @@ void cProtocol_1_8_0::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlo void cProtocol_1_8_0::SendCameraSetTo(const cEntity & a_Entity) { - cPacketizer Pkt(*this, 0x43); // Camera Packet (Attach the camera of a player at another entity in spectator mode) - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + cPacketizer Pkt(*this, 0x43); // Camera Packet (Attach the camera of a player at another entity in spectator mode) + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); } @@ -257,9 +257,9 @@ void cProtocol_1_8_0::SendCameraSetTo(const cEntity & a_Entity) void cProtocol_1_8_0::SendChat(const AString & a_Message, eChatType a_Type) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - SendChatRaw(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()), a_Type); + SendChatRaw(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()), a_Type); } @@ -268,9 +268,9 @@ void cProtocol_1_8_0::SendChat(const AString & a_Message, eChatType a_Type) void cProtocol_1_8_0::SendChat(const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - SendChatRaw(a_Message.CreateJsonString(a_ShouldUseChatPrefixes), a_Type); + SendChatRaw(a_Message.CreateJsonString(a_ShouldUseChatPrefixes), a_Type); } @@ -279,12 +279,12 @@ void cProtocol_1_8_0::SendChat(const cCompositeChat & a_Message, eChatType a_Typ void cProtocol_1_8_0::SendChatRaw(const AString & a_MessageRaw, eChatType a_Type) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - // Send the json string to the client: - cPacketizer Pkt(*this, 0x02); - Pkt.WriteString(a_MessageRaw); - Pkt.WriteBEInt8(a_Type); + // Send the json string to the client: + cPacketizer Pkt(*this, 0x02); + Pkt.WriteString(a_MessageRaw); + Pkt.WriteBEInt8(a_Type); } @@ -293,14 +293,14 @@ void cProtocol_1_8_0::SendChatRaw(const AString & a_MessageRaw, eChatType a_Type void cProtocol_1_8_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - // Serialize first, before creating the Packetizer (the packetizer locks a CS) - // This contains the flags and bitmasks, too - const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ); + // Serialize first, before creating the Packetizer (the packetizer locks a CS) + // This contains the flags and bitmasks, too + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ); - cCSLock Lock(m_CSPacket); - SendData(ChunkData.data(), ChunkData.size()); + cCSLock Lock(m_CSPacket); + SendData(ChunkData.data(), ChunkData.size()); } @@ -309,12 +309,12 @@ void cProtocol_1_8_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerial void cProtocol_1_8_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) { - UNUSED(a_Count); - ASSERT(m_State == 3); // In game mode? + UNUSED(a_Count); + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0d); // Collect Item packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteVarInt32(a_Player.GetUniqueID()); + cPacketizer Pkt(*this, 0x0d); // Collect Item packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteVarInt32(a_Player.GetUniqueID()); } @@ -323,11 +323,11 @@ void cProtocol_1_8_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer void cProtocol_1_8_0::SendDestroyEntity(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x13); // Destroy Entities packet - Pkt.WriteVarInt32(1); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + cPacketizer Pkt(*this, 0x13); // Destroy Entities packet + Pkt.WriteVarInt32(1); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); } @@ -336,12 +336,12 @@ void cProtocol_1_8_0::SendDestroyEntity(const cEntity & a_Entity) void cProtocol_1_8_0::SendDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1b); // Attach Entity packet - Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt32(0); - Pkt.WriteBool(false); + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet + Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt32(0); + Pkt.WriteBool(false); } @@ -350,23 +350,23 @@ void cProtocol_1_8_0::SendDetachEntity(const cEntity & a_Entity, const cEntity & void cProtocol_1_8_0::SendDisconnect(const AString & a_Reason) { - switch (m_State) - { - case 2: - { - // During login: - cPacketizer Pkt(*this, 0); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); - break; - } - case 3: - { - // In-game: - cPacketizer Pkt(*this, 0x40); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); - break; - } - } + switch (m_State) + { + case 2: + { + // During login: + cPacketizer Pkt(*this, 0); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); + break; + } + case 3: + { + // In-game: + cPacketizer Pkt(*this, 0x40); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); + break; + } + } } @@ -375,10 +375,10 @@ void cProtocol_1_8_0::SendDisconnect(const AString & a_Reason) void cProtocol_1_8_0::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); } @@ -387,14 +387,14 @@ void cProtocol_1_8_0::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) void cProtocol_1_8_0::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1D); // Entity Effect packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_Amplifier)); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Duration)); - Pkt.WriteBool(false); // Hide particles + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Amplifier)); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Duration)); + Pkt.WriteBool(false); // Hide particles } @@ -403,12 +403,12 @@ void cProtocol_1_8_0::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, void cProtocol_1_8_0::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x04); // Entity Equipment packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt16(a_SlotNum); - WriteItem(Pkt, a_Item); + cPacketizer Pkt(*this, 0x04); // Entity Equipment packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt16(a_SlotNum); + WriteItem(Pkt, a_Item); } @@ -417,11 +417,11 @@ void cProtocol_1_8_0::SendEntityEquipment(const cEntity & a_Entity, short a_Slot void cProtocol_1_8_0::SendEntityHeadLook(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x19); // Entity Head Look packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); + cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); } @@ -430,13 +430,13 @@ void cProtocol_1_8_0::SendEntityHeadLook(const cEntity & a_Entity) void cProtocol_1_8_0::SendEntityLook(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x16); // Entity Look packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(a_Entity.IsOnGround()); + cPacketizer Pkt(*this, 0x16); // Entity Look packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(a_Entity.IsOnGround()); } @@ -445,12 +445,12 @@ void cProtocol_1_8_0::SendEntityLook(const cEntity & a_Entity) void cProtocol_1_8_0::SendEntityMetadata(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - WriteEntityMetadata(Pkt, a_Entity); - Pkt.WriteBEUInt8(0x7f); // The termination byte + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + WriteEntityMetadata(Pkt, a_Entity); + Pkt.WriteBEUInt8(0x7f); // The termination byte } @@ -459,11 +459,11 @@ void cProtocol_1_8_0::SendEntityMetadata(const cEntity & a_Entity) void cProtocol_1_8_0::SendEntityProperties(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x20); // Entity Properties packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - WriteEntityProperties(Pkt, a_Entity); + cPacketizer Pkt(*this, 0x20); // Entity Properties packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + WriteEntityProperties(Pkt, a_Entity); } @@ -472,14 +472,14 @@ void cProtocol_1_8_0::SendEntityProperties(const cEntity & a_Entity) void cProtocol_1_8_0::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt8(a_RelX); - Pkt.WriteBEInt8(a_RelY); - Pkt.WriteBEInt8(a_RelZ); - Pkt.WriteBool(a_Entity.IsOnGround()); + cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt8(a_RelX); + Pkt.WriteBEInt8(a_RelY); + Pkt.WriteBEInt8(a_RelZ); + Pkt.WriteBool(a_Entity.IsOnGround()); } @@ -488,16 +488,16 @@ void cProtocol_1_8_0::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, c void cProtocol_1_8_0::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt8(a_RelX); - Pkt.WriteBEInt8(a_RelY); - Pkt.WriteBEInt8(a_RelZ); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(a_Entity.IsOnGround()); + cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt8(a_RelX); + Pkt.WriteBEInt8(a_RelY); + Pkt.WriteBEInt8(a_RelZ); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(a_Entity.IsOnGround()); } @@ -506,11 +506,11 @@ void cProtocol_1_8_0::SendEntityRelMoveLook(const cEntity & a_Entity, char a_Rel void cProtocol_1_8_0::SendEntityStatus(const cEntity & a_Entity, char a_Status) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1a); // Entity Status packet - Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt8(a_Status); + cPacketizer Pkt(*this, 0x1a); // Entity Status packet + Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt8(a_Status); } @@ -519,14 +519,14 @@ void cProtocol_1_8_0::SendEntityStatus(const cEntity & a_Entity, char a_Status) void cProtocol_1_8_0::SendEntityVelocity(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x12); // Entity Velocity packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400)); + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400)); } @@ -535,23 +535,23 @@ void cProtocol_1_8_0::SendEntityVelocity(const cEntity & a_Entity) void cProtocol_1_8_0::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x27); // Explosion packet - Pkt.WriteBEFloat(static_cast<float>(a_BlockX)); - Pkt.WriteBEFloat(static_cast<float>(a_BlockY)); - Pkt.WriteBEFloat(static_cast<float>(a_BlockZ)); - Pkt.WriteBEFloat(static_cast<float>(a_Radius)); - Pkt.WriteBEUInt32(static_cast<UInt32>(a_BlocksAffected.size())); - for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(), end = a_BlocksAffected.end(); itr != end; ++itr) - { - Pkt.WriteBEInt8(static_cast<Int8>(itr->x)); - Pkt.WriteBEInt8(static_cast<Int8>(itr->y)); - Pkt.WriteBEInt8(static_cast<Int8>(itr->z)); - } // for itr - a_BlockAffected[] - Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.x)); - Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.y)); - Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.z)); + cPacketizer Pkt(*this, 0x27); // Explosion packet + Pkt.WriteBEFloat(static_cast<float>(a_BlockX)); + Pkt.WriteBEFloat(static_cast<float>(a_BlockY)); + Pkt.WriteBEFloat(static_cast<float>(a_BlockZ)); + Pkt.WriteBEFloat(static_cast<float>(a_Radius)); + Pkt.WriteBEUInt32(static_cast<UInt32>(a_BlocksAffected.size())); + for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(), end = a_BlocksAffected.end(); itr != end; ++itr) + { + Pkt.WriteBEInt8(static_cast<Int8>(itr->x)); + Pkt.WriteBEInt8(static_cast<Int8>(itr->y)); + Pkt.WriteBEInt8(static_cast<Int8>(itr->z)); + } // for itr - a_BlockAffected[] + Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.x)); + Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.y)); + Pkt.WriteBEFloat(static_cast<float>(a_PlayerMotion.z)); } @@ -560,11 +560,11 @@ void cProtocol_1_8_0::SendExplosion(double a_BlockX, double a_BlockY, double a_B void cProtocol_1_8_0::SendGameMode(eGameMode a_GameMode) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x2b); // Change Game State packet - Pkt.WriteBEUInt8(3); // Reason: Change game mode - Pkt.WriteBEFloat(static_cast<float>(a_GameMode)); // The protocol really represents the value with a float! + cPacketizer Pkt(*this, 0x2b); // Change Game State packet + Pkt.WriteBEUInt8(3); // Reason: Change game mode + Pkt.WriteBEFloat(static_cast<float>(a_GameMode)); // The protocol really represents the value with a float! } @@ -573,13 +573,13 @@ void cProtocol_1_8_0::SendGameMode(eGameMode a_GameMode) void cProtocol_1_8_0::SendHealth(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x06); // Update Health packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteBEFloat(static_cast<float>(Player->GetHealth())); - Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetFoodLevel())); - Pkt.WriteBEFloat(static_cast<float>(Player->GetFoodSaturationLevel())); + cPacketizer Pkt(*this, 0x06); // Update Health packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEFloat(static_cast<float>(Player->GetHealth())); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetFoodLevel())); + Pkt.WriteBEFloat(static_cast<float>(Player->GetFoodSaturationLevel())); } @@ -588,10 +588,10 @@ void cProtocol_1_8_0::SendHealth(void) void cProtocol_1_8_0::SendHideTitle(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x45); // Title packet - Pkt.WriteVarInt32(3); // Hide title + cPacketizer Pkt(*this, 0x45); // Title packet + Pkt.WriteVarInt32(3); // Hide title } @@ -600,12 +600,12 @@ void cProtocol_1_8_0::SendHideTitle(void) void cProtocol_1_8_0::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x2f); // Set Slot packet - Pkt.WriteBEInt8(a_WindowID); - Pkt.WriteBEInt16(a_SlotNum); - WriteItem(Pkt, a_Item); + cPacketizer Pkt(*this, 0x2f); // Set Slot packet + Pkt.WriteBEInt8(a_WindowID); + Pkt.WriteBEInt16(a_SlotNum); + WriteItem(Pkt, a_Item); } @@ -614,15 +614,15 @@ void cProtocol_1_8_0::SendInventorySlot(char a_WindowID, short a_SlotNum, const void cProtocol_1_8_0::SendKeepAlive(UInt32 a_PingID) { - // Drop the packet if the protocol is not in the Game state yet (caused a client crash): - if (m_State != 3) - { - LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); - return; - } + // Drop the packet if the protocol is not in the Game state yet (caused a client crash): + if (m_State != 3) + { + LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); + return; + } - cPacketizer Pkt(*this, 0x00); // Keep Alive packet - Pkt.WriteVarInt32(a_PingID); + cPacketizer Pkt(*this, 0x00); // Keep Alive packet + Pkt.WriteVarInt32(a_PingID); } @@ -631,12 +631,12 @@ void cProtocol_1_8_0::SendKeepAlive(UInt32 a_PingID) void cProtocol_1_8_0::SendLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1b); // Attach Entity packet - Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt32(a_EntityLeashedTo.GetUniqueID()); - Pkt.WriteBool(true); + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet + Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt32(a_EntityLeashedTo.GetUniqueID()); + Pkt.WriteBool(true); } @@ -645,12 +645,12 @@ void cProtocol_1_8_0::SendLeashEntity(const cEntity & a_Entity, const cEntity & void cProtocol_1_8_0::SendUnleashEntity(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1b); // Attach Entity packet - Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt32(-1); - Pkt.WriteBool(true); + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet + Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt32(-1); + Pkt.WriteBool(true); } @@ -659,33 +659,33 @@ void cProtocol_1_8_0::SendUnleashEntity(const cEntity & a_Entity) void cProtocol_1_8_0::SendLogin(const cPlayer & a_Player, const cWorld & a_World) { - // Send the Join Game packet: - { - cServer * Server = cRoot::Get()->GetServer(); - cPacketizer Pkt(*this, 0x01); // Join Game packet - Pkt.WriteBEUInt32(a_Player.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 - Pkt.WriteBEInt8(static_cast<Int8>(a_World.GetDimension())); - Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) - Pkt.WriteBEUInt8(static_cast<UInt8>(Clamp<size_t>(Server->GetMaxPlayers(), 0, 255))); - Pkt.WriteString("default"); // Level type - wtf? - Pkt.WriteBool(false); // Reduced Debug Info - wtf? - } + // Send the Join Game packet: + { + cServer * Server = cRoot::Get()->GetServer(); + cPacketizer Pkt(*this, 0x01); // Join Game packet + Pkt.WriteBEUInt32(a_Player.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 + Pkt.WriteBEInt8(static_cast<Int8>(a_World.GetDimension())); + Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) + Pkt.WriteBEUInt8(static_cast<UInt8>(Clamp<size_t>(Server->GetMaxPlayers(), 0, 255))); + Pkt.WriteString("default"); // Level type - wtf? + Pkt.WriteBool(false); // Reduced Debug Info - wtf? + } - // Send the spawn position: - { - cPacketizer Pkt(*this, 0x05); // Spawn Position packet - Pkt.WritePosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); - } + // Send the spawn position: + { + cPacketizer Pkt(*this, 0x05); // Spawn Position packet + Pkt.WritePosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); + } - // Send the server difficulty: - { - cPacketizer Pkt(*this, 0x41); - Pkt.WriteBEInt8(1); - } + // Send the server difficulty: + { + cPacketizer Pkt(*this, 0x41); + Pkt.WriteBEInt8(1); + } - // Send player abilities: - SendPlayerAbilities(); + // Send player abilities: + SendPlayerAbilities(); } @@ -693,21 +693,21 @@ void cProtocol_1_8_0::SendLogin(const cPlayer & a_Player, const cWorld & a_World void cProtocol_1_8_0::SendLoginSuccess(void) { - ASSERT(m_State == 2); // State: login? + ASSERT(m_State == 2); // State: login? - // Enable compression: - { - cPacketizer Pkt(*this, 0x03); // Set compression packet - Pkt.WriteVarInt32(256); - } + // Enable compression: + { + cPacketizer Pkt(*this, 0x03); // Set compression packet + Pkt.WriteVarInt32(256); + } - m_State = 3; // State = Game + m_State = 3; // State = Game - { - cPacketizer Pkt(*this, 0x02); // Login success packet - Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); - Pkt.WriteString(m_Client->GetUsername()); - } + { + cPacketizer Pkt(*this, 0x02); // Login success packet + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); + Pkt.WriteString(m_Client->GetUsername()); + } } @@ -716,16 +716,16 @@ void cProtocol_1_8_0::SendLoginSuccess(void) void cProtocol_1_8_0::SendPaintingSpawn(const cPainting & a_Painting) { - ASSERT(m_State == 3); // In game mode? - double PosX = a_Painting.GetPosX(); - double PosY = a_Painting.GetPosY(); - double PosZ = a_Painting.GetPosZ(); + ASSERT(m_State == 3); // In game mode? + double PosX = a_Painting.GetPosX(); + double PosY = a_Painting.GetPosY(); + double PosZ = a_Painting.GetPosZ(); - cPacketizer Pkt(*this, 0x10); // Spawn Painting packet - Pkt.WriteVarInt32(a_Painting.GetUniqueID()); - Pkt.WriteString(a_Painting.GetName().c_str()); - Pkt.WritePosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); - Pkt.WriteBEInt8(static_cast<Int8>(a_Painting.GetProtocolFacing())); + cPacketizer Pkt(*this, 0x10); // Spawn Painting packet + Pkt.WriteVarInt32(a_Painting.GetUniqueID()); + Pkt.WriteString(a_Painting.GetName().c_str()); + Pkt.WritePosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); + Pkt.WriteBEInt8(static_cast<Int8>(a_Painting.GetProtocolFacing())); } @@ -734,29 +734,29 @@ void cProtocol_1_8_0::SendPaintingSpawn(const cPainting & a_Painting) void cProtocol_1_8_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataStartY) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x34); - Pkt.WriteVarInt32(a_Map.GetID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_Map.GetScale())); + cPacketizer Pkt(*this, 0x34); + Pkt.WriteVarInt32(a_Map.GetID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Map.GetScale())); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Map.GetDecorators().size())); - for (const auto & Decorator : a_Map.GetDecorators()) - { - Pkt.WriteBEUInt8(static_cast<Byte>((static_cast<Int32>(Decorator.GetType()) << 4) | (Decorator.GetRot() & 0xF))); - Pkt.WriteBEUInt8(static_cast<UInt8>(Decorator.GetPixelX())); - Pkt.WriteBEUInt8(static_cast<UInt8>(Decorator.GetPixelZ())); - } + Pkt.WriteVarInt32(static_cast<UInt32>(a_Map.GetDecorators().size())); + for (const auto & Decorator : a_Map.GetDecorators()) + { + Pkt.WriteBEUInt8(static_cast<Byte>((static_cast<Int32>(Decorator.GetType()) << 4) | (Decorator.GetRot() & 0xF))); + Pkt.WriteBEUInt8(static_cast<UInt8>(Decorator.GetPixelX())); + Pkt.WriteBEUInt8(static_cast<UInt8>(Decorator.GetPixelZ())); + } - Pkt.WriteBEUInt8(128); - Pkt.WriteBEUInt8(128); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_DataStartX)); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_DataStartY)); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Map.GetData().size())); - for (auto itr = a_Map.GetData().cbegin(); itr != a_Map.GetData().cend(); ++itr) - { - Pkt.WriteBEUInt8(*itr); - } + Pkt.WriteBEUInt8(128); + Pkt.WriteBEUInt8(128); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_DataStartX)); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_DataStartY)); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Map.GetData().size())); + for (auto itr = a_Map.GetData().cbegin(); itr != a_Map.GetData().cend(); ++itr) + { + Pkt.WriteBEUInt8(*itr); + } } @@ -765,27 +765,27 @@ void cProtocol_1_8_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da void cProtocol_1_8_0::SendPickupSpawn(const cPickup & a_Pickup) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - { - cPacketizer Pkt(*this, 0x0e); // Spawn Object packet - Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); - Pkt.WriteBEUInt8(2); // Type = Pickup - Pkt.WriteFPInt(a_Pickup.GetPosX()); - Pkt.WriteFPInt(a_Pickup.GetPosY()); - Pkt.WriteFPInt(a_Pickup.GetPosZ()); - Pkt.WriteByteAngle(a_Pickup.GetYaw()); - Pkt.WriteByteAngle(a_Pickup.GetPitch()); - Pkt.WriteBEInt32(0); // No object data - } + { + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet + Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); + Pkt.WriteBEUInt8(2); // Type = Pickup + Pkt.WriteFPInt(a_Pickup.GetPosX()); + Pkt.WriteFPInt(a_Pickup.GetPosY()); + Pkt.WriteFPInt(a_Pickup.GetPosZ()); + Pkt.WriteByteAngle(a_Pickup.GetYaw()); + Pkt.WriteByteAngle(a_Pickup.GetPitch()); + Pkt.WriteBEInt32(0); // No object data + } - { - cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet - Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); - Pkt.WriteBEUInt8((0x05 << 5) | 10); // Slot type + index 10 - WriteItem(Pkt, a_Pickup.GetItem()); - Pkt.WriteBEUInt8(0x7f); // End of metadata - } + { + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); + Pkt.WriteBEUInt8((0x05 << 5) | 10); // Slot type + index 10 + WriteItem(Pkt, a_Pickup.GetItem()); + Pkt.WriteBEUInt8(0x7f); // End of metadata + } } @@ -794,27 +794,27 @@ void cProtocol_1_8_0::SendPickupSpawn(const cPickup & a_Pickup) void cProtocol_1_8_0::SendPlayerAbilities(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x39); // Player Abilities packet - Byte Flags = 0; - cPlayer * Player = m_Client->GetPlayer(); - if (Player->IsGameModeCreative()) - { - Flags |= 0x01; - Flags |= 0x08; // Godmode, used for creative - } - if (Player->IsFlying()) - { - Flags |= 0x02; - } - if (Player->CanFly()) - { - Flags |= 0x04; - } - Pkt.WriteBEUInt8(Flags); - Pkt.WriteBEFloat(static_cast<float>(0.05 * Player->GetFlyingMaxSpeed())); - Pkt.WriteBEFloat(static_cast<float>(0.1 * Player->GetNormalMaxSpeed())); + cPacketizer Pkt(*this, 0x39); // Player Abilities packet + Byte Flags = 0; + cPlayer * Player = m_Client->GetPlayer(); + if (Player->IsGameModeCreative()) + { + Flags |= 0x01; + Flags |= 0x08; // Godmode, used for creative + } + if (Player->IsFlying()) + { + Flags |= 0x02; + } + if (Player->CanFly()) + { + Flags |= 0x04; + } + Pkt.WriteBEUInt8(Flags); + Pkt.WriteBEFloat(static_cast<float>(0.05 * Player->GetFlyingMaxSpeed())); + Pkt.WriteBEFloat(static_cast<float>(0.1 * Player->GetNormalMaxSpeed())); } @@ -823,11 +823,11 @@ void cProtocol_1_8_0::SendPlayerAbilities(void) void cProtocol_1_8_0::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0b); // Animation packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEInt8(a_Animation); + cPacketizer Pkt(*this, 0x0b); // Animation packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt8(a_Animation); } @@ -836,20 +836,20 @@ void cProtocol_1_8_0::SendEntityAnimation(const cEntity & a_Entity, char a_Anima void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { - ASSERT(m_State == 3); // In game mode? - int ParticleID = GetParticleID(a_ParticleName); + ASSERT(m_State == 3); // In game mode? + int ParticleID = GetParticleID(a_ParticleName); - cPacketizer Pkt(*this, 0x2A); - Pkt.WriteBEInt32(ParticleID); - Pkt.WriteBool(false); - Pkt.WriteBEFloat(a_SrcX); - Pkt.WriteBEFloat(a_SrcY); - Pkt.WriteBEFloat(a_SrcZ); - Pkt.WriteBEFloat(a_OffsetX); - Pkt.WriteBEFloat(a_OffsetY); - Pkt.WriteBEFloat(a_OffsetZ); - Pkt.WriteBEFloat(a_ParticleData); - Pkt.WriteBEInt32(a_ParticleAmount); + cPacketizer Pkt(*this, 0x2A); + Pkt.WriteBEInt32(ParticleID); + Pkt.WriteBool(false); + Pkt.WriteBEFloat(a_SrcX); + Pkt.WriteBEFloat(a_SrcY); + Pkt.WriteBEFloat(a_SrcZ); + Pkt.WriteBEFloat(a_OffsetX); + Pkt.WriteBEFloat(a_OffsetY); + Pkt.WriteBEFloat(a_OffsetZ); + Pkt.WriteBEFloat(a_ParticleData); + Pkt.WriteBEInt32(a_ParticleAmount); } @@ -858,42 +858,42 @@ void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, float a void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) { - ASSERT(m_State == 3); // In game mode? - int ParticleID = GetParticleID(a_ParticleName); - - cPacketizer Pkt(*this, 0x2A); - Pkt.WriteBEInt32(ParticleID); - Pkt.WriteBool(false); - Pkt.WriteBEFloat(a_Src.x); - Pkt.WriteBEFloat(a_Src.y); - Pkt.WriteBEFloat(a_Src.z); - Pkt.WriteBEFloat(a_Offset.x); - Pkt.WriteBEFloat(a_Offset.y); - Pkt.WriteBEFloat(a_Offset.z); - Pkt.WriteBEFloat(a_ParticleData); - Pkt.WriteBEInt32(a_ParticleAmount); - switch (ParticleID) - { - // iconcrack - case 36: - { - Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0])); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[1])); - break; - } - // blockcrack - // blockdust - case 37: - case 38: - { - Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0])); - break; - } - default: - { - break; - } - } + ASSERT(m_State == 3); // In game mode? + int ParticleID = GetParticleID(a_ParticleName); + + cPacketizer Pkt(*this, 0x2A); + Pkt.WriteBEInt32(ParticleID); + Pkt.WriteBool(false); + Pkt.WriteBEFloat(a_Src.x); + Pkt.WriteBEFloat(a_Src.y); + Pkt.WriteBEFloat(a_Src.z); + Pkt.WriteBEFloat(a_Offset.x); + Pkt.WriteBEFloat(a_Offset.y); + Pkt.WriteBEFloat(a_Offset.z); + Pkt.WriteBEFloat(a_ParticleData); + Pkt.WriteBEInt32(a_ParticleAmount); + switch (ParticleID) + { + // iconcrack + case 36: + { + Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0])); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[1])); + break; + } + // blockcrack + // blockdust + case 37: + case 38: + { + Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0])); + break; + } + default: + { + break; + } + } } @@ -902,35 +902,35 @@ void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, Vector3 void cProtocol_1_8_0::SendPlayerListAddPlayer(const cPlayer & a_Player) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt32(0); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); - Pkt.WriteString(a_Player.GetPlayerListName()); + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt32(0); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteString(a_Player.GetPlayerListName()); - const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); - Pkt.WriteVarInt32(Properties.size()); - for (auto & Node : Properties) - { - Pkt.WriteString(Node.get("name", "").asString()); - Pkt.WriteString(Node.get("value", "").asString()); - AString Signature = Node.get("signature", "").asString(); - if (Signature.empty()) - { - Pkt.WriteBool(false); - } - else - { - Pkt.WriteBool(true); - Pkt.WriteString(Signature); - } - } + const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); + Pkt.WriteVarInt32(Properties.size()); + for (auto & Node : Properties) + { + Pkt.WriteString(Node.get("name", "").asString()); + Pkt.WriteString(Node.get("value", "").asString()); + AString Signature = Node.get("signature", "").asString(); + if (Signature.empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Signature); + } + } - Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetClientHandle()->GetPing())); - Pkt.WriteBool(false); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetClientHandle()->GetPing())); + Pkt.WriteBool(false); } @@ -939,12 +939,12 @@ void cProtocol_1_8_0::SendPlayerListAddPlayer(const cPlayer & a_Player) void cProtocol_1_8_0::SendPlayerListRemovePlayer(const cPlayer & a_Player) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt32(4); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt32(4); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); } @@ -953,13 +953,13 @@ void cProtocol_1_8_0::SendPlayerListRemovePlayer(const cPlayer & a_Player) void cProtocol_1_8_0::SendPlayerListUpdateGameMode(const cPlayer & a_Player) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt32(1); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt32(1); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); } @@ -968,17 +968,17 @@ void cProtocol_1_8_0::SendPlayerListUpdateGameMode(const cPlayer & a_Player) void cProtocol_1_8_0::SendPlayerListUpdatePing(const cPlayer & a_Player) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - auto ClientHandle = a_Player.GetClientHandlePtr(); - if (ClientHandle != nullptr) - { - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt32(2); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); - Pkt.WriteVarInt32(static_cast<UInt32>(ClientHandle->GetPing())); - } + auto ClientHandle = a_Player.GetClientHandlePtr(); + if (ClientHandle != nullptr) + { + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt32(2); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt32(static_cast<UInt32>(ClientHandle->GetPing())); + } } @@ -987,22 +987,22 @@ void cProtocol_1_8_0::SendPlayerListUpdatePing(const cPlayer & a_Player) void cProtocol_1_8_0::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt32(3); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt32(3); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); - if (a_CustomName.empty()) - { - Pkt.WriteBool(false); - } - else - { - Pkt.WriteBool(true); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_CustomName.c_str())); - } + if (a_CustomName.empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_CustomName.c_str())); + } } @@ -1011,27 +1011,27 @@ void cProtocol_1_8_0::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, void cProtocol_1_8_0::SendPlayerMaxSpeed(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x20); // Entity Properties - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteVarInt32(Player->GetUniqueID()); - Pkt.WriteBEInt32(1); // Count - Pkt.WriteString("generic.movementSpeed"); - // The default game speed is 0.1, multiply that value by the relative speed: - Pkt.WriteBEDouble(0.1 * Player->GetNormalMaxSpeed()); - if (Player->IsSprinting()) - { - Pkt.WriteVarInt32(1); // Modifier count - Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); - Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier - Pkt.WriteBEDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); - Pkt.WriteBEUInt8(2); - } - else - { - Pkt.WriteVarInt32(0); // Modifier count - } + cPacketizer Pkt(*this, 0x20); // Entity Properties + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteVarInt32(Player->GetUniqueID()); + Pkt.WriteBEInt32(1); // Count + Pkt.WriteString("generic.movementSpeed"); + // The default game speed is 0.1, multiply that value by the relative speed: + Pkt.WriteBEDouble(0.1 * Player->GetNormalMaxSpeed()); + if (Player->IsSprinting()) + { + Pkt.WriteVarInt32(1); // Modifier count + Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); + Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier + Pkt.WriteBEDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); + Pkt.WriteBEUInt8(2); + } + else + { + Pkt.WriteVarInt32(0); // Modifier count + } } @@ -1040,16 +1040,16 @@ void cProtocol_1_8_0::SendPlayerMaxSpeed(void) void cProtocol_1_8_0::SendPlayerMoveLook(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x08); // Player Position And Look packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteBEDouble(Player->GetPosX()); - Pkt.WriteBEDouble(Player->GetPosY()); - Pkt.WriteBEDouble(Player->GetPosZ()); - Pkt.WriteBEFloat(static_cast<float>(Player->GetYaw())); - Pkt.WriteBEFloat(static_cast<float>(Player->GetPitch())); - Pkt.WriteBEUInt8(0); + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEDouble(Player->GetPosX()); + Pkt.WriteBEDouble(Player->GetPosY()); + Pkt.WriteBEDouble(Player->GetPosZ()); + Pkt.WriteBEFloat(static_cast<float>(Player->GetYaw())); + Pkt.WriteBEFloat(static_cast<float>(Player->GetPitch())); + Pkt.WriteBEUInt8(0); } @@ -1058,8 +1058,8 @@ void cProtocol_1_8_0::SendPlayerMoveLook(void) void cProtocol_1_8_0::SendPlayerPosition(void) { - // There is no dedicated packet for this, send the whole thing: - SendPlayerMoveLook(); + // There is no dedicated packet for this, send the whole thing: + SendPlayerMoveLook(); } @@ -1068,22 +1068,22 @@ void cProtocol_1_8_0::SendPlayerPosition(void) void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player) { - // Called to spawn another player for the client - cPacketizer Pkt(*this, 0x0c); // Spawn Player packet - Pkt.WriteVarInt32(a_Player.GetUniqueID()); - Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID())); - Pkt.WriteFPInt(a_Player.GetPosX()); - Pkt.WriteFPInt(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. - Pkt.WriteFPInt(a_Player.GetPosZ()); - Pkt.WriteByteAngle(a_Player.GetYaw()); - Pkt.WriteByteAngle(a_Player.GetPitch()); - short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; - Pkt.WriteBEInt16(ItemType); - Pkt.WriteBEUInt8((3 << 5) | 6); // Metadata: float + index 6 - Pkt.WriteBEFloat(static_cast<float>(a_Player.GetHealth())); - Pkt.WriteBEUInt8((4 << 5 | (2 & 0x1F)) & 0xFF); - Pkt.WriteString(a_Player.GetName()); - Pkt.WriteBEUInt8(0x7f); // Metadata: end + // Called to spawn another player for the client + cPacketizer Pkt(*this, 0x0c); // Spawn Player packet + Pkt.WriteVarInt32(a_Player.GetUniqueID()); + Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID())); + Pkt.WriteFPInt(a_Player.GetPosX()); + Pkt.WriteFPInt(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. + Pkt.WriteFPInt(a_Player.GetPosZ()); + Pkt.WriteByteAngle(a_Player.GetYaw()); + Pkt.WriteByteAngle(a_Player.GetPitch()); + short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; + Pkt.WriteBEInt16(ItemType); + Pkt.WriteBEUInt8((3 << 5) | 6); // Metadata: float + index 6 + Pkt.WriteBEFloat(static_cast<float>(a_Player.GetHealth())); + Pkt.WriteBEUInt8((4 << 5 | (2 & 0x1F)) & 0xFF); + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteBEUInt8(0x7f); // Metadata: end } @@ -1092,11 +1092,11 @@ void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player) void cProtocol_1_8_0::SendPluginMessage(const AString & a_Channel, const AString & a_Message) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3f); - Pkt.WriteString(a_Channel); - Pkt.WriteBuf(a_Message.data(), a_Message.size()); + cPacketizer Pkt(*this, 0x3f); + Pkt.WriteString(a_Channel); + Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -1105,11 +1105,11 @@ void cProtocol_1_8_0::SendPluginMessage(const AString & a_Channel, const AString void cProtocol_1_8_0::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1e); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); + cPacketizer Pkt(*this, 0x1e); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); } @@ -1118,10 +1118,10 @@ void cProtocol_1_8_0::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Eff void cProtocol_1_8_0::SendResetTitle(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x45); // Title packet - Pkt.WriteVarInt32(4); // Reset title + cPacketizer Pkt(*this, 0x45); // Title packet + Pkt.WriteVarInt32(4); // Reset title } @@ -1131,12 +1131,12 @@ void cProtocol_1_8_0::SendResetTitle(void) void cProtocol_1_8_0::SendRespawn(eDimension a_Dimension) { - cPacketizer Pkt(*this, 0x07); // Respawn packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteBEInt32(static_cast<Int32>(a_Dimension)); - Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) - Pkt.WriteBEUInt8(static_cast<Byte>(Player->GetEffectiveGameMode())); - Pkt.WriteString("default"); + cPacketizer Pkt(*this, 0x07); // Respawn packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEInt32(static_cast<Int32>(a_Dimension)); + Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) + Pkt.WriteBEUInt8(static_cast<Byte>(Player->GetEffectiveGameMode())); + Pkt.WriteString("default"); } @@ -1145,13 +1145,13 @@ void cProtocol_1_8_0::SendRespawn(eDimension a_Dimension) void cProtocol_1_8_0::SendExperience(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1f); // Experience Packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteBEFloat(Player->GetXpPercentage()); - Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetXpLevel())); - Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetCurrentXp())); + cPacketizer Pkt(*this, 0x1f); // Experience Packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEFloat(Player->GetXpPercentage()); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetXpLevel())); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetCurrentXp())); } @@ -1160,14 +1160,14 @@ void cProtocol_1_8_0::SendExperience(void) void cProtocol_1_8_0::SendExperienceOrb(const cExpOrb & a_ExpOrb) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x11); - Pkt.WriteVarInt32(a_ExpOrb.GetUniqueID()); - Pkt.WriteFPInt(a_ExpOrb.GetPosX()); - Pkt.WriteFPInt(a_ExpOrb.GetPosY()); - Pkt.WriteFPInt(a_ExpOrb.GetPosZ()); - Pkt.WriteBEInt16(static_cast<Int16>(a_ExpOrb.GetReward())); + cPacketizer Pkt(*this, 0x11); + Pkt.WriteVarInt32(a_ExpOrb.GetUniqueID()); + Pkt.WriteFPInt(a_ExpOrb.GetPosX()); + Pkt.WriteFPInt(a_ExpOrb.GetPosY()); + Pkt.WriteFPInt(a_ExpOrb.GetPosZ()); + Pkt.WriteBEInt16(static_cast<Int16>(a_ExpOrb.GetReward())); } @@ -1176,16 +1176,16 @@ void cProtocol_1_8_0::SendExperienceOrb(const cExpOrb & a_ExpOrb) void cProtocol_1_8_0::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3b); - Pkt.WriteString(a_Name); - Pkt.WriteBEUInt8(a_Mode); - if ((a_Mode == 0) || (a_Mode == 2)) - { - Pkt.WriteString(a_DisplayName); - Pkt.WriteString("integer"); - } + cPacketizer Pkt(*this, 0x3b); + Pkt.WriteString(a_Name); + Pkt.WriteBEUInt8(a_Mode); + if ((a_Mode == 0) || (a_Mode == 2)) + { + Pkt.WriteString(a_DisplayName); + Pkt.WriteString("integer"); + } } @@ -1194,17 +1194,17 @@ void cProtocol_1_8_0::SendScoreboardObjective(const AString & a_Name, const AStr void cProtocol_1_8_0::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3c); - Pkt.WriteString(a_Player); - Pkt.WriteBEUInt8(a_Mode); - Pkt.WriteString(a_Objective); + cPacketizer Pkt(*this, 0x3c); + Pkt.WriteString(a_Player); + Pkt.WriteBEUInt8(a_Mode); + Pkt.WriteString(a_Objective); - if (a_Mode != 1) - { - Pkt.WriteVarInt32(static_cast<UInt32>(a_Score)); - } + if (a_Mode != 1) + { + Pkt.WriteVarInt32(static_cast<UInt32>(a_Score)); + } } @@ -1213,11 +1213,11 @@ void cProtocol_1_8_0::SendScoreUpdate(const AString & a_Objective, const AString void cProtocol_1_8_0::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3d); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_Display)); - Pkt.WriteString(a_Objective); + cPacketizer Pkt(*this, 0x3d); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Display)); + Pkt.WriteString(a_Objective); } @@ -1226,7 +1226,7 @@ void cProtocol_1_8_0::SendDisplayObjective(const AString & a_Objective, cScorebo void cProtocol_1_8_0::SendSetSubTitle(const cCompositeChat & a_SubTitle) { - SendSetRawSubTitle(a_SubTitle.CreateJsonString(false)); + SendSetRawSubTitle(a_SubTitle.CreateJsonString(false)); } @@ -1235,12 +1235,12 @@ void cProtocol_1_8_0::SendSetSubTitle(const cCompositeChat & a_SubTitle) void cProtocol_1_8_0::SendSetRawSubTitle(const AString & a_SubTitle) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x45); // Title packet - Pkt.WriteVarInt32(1); // Set subtitle + cPacketizer Pkt(*this, 0x45); // Title packet + Pkt.WriteVarInt32(1); // Set subtitle - Pkt.WriteString(a_SubTitle); + Pkt.WriteString(a_SubTitle); } @@ -1249,7 +1249,7 @@ void cProtocol_1_8_0::SendSetRawSubTitle(const AString & a_SubTitle) void cProtocol_1_8_0::SendSetTitle(const cCompositeChat & a_Title) { - SendSetRawTitle(a_Title.CreateJsonString(false)); + SendSetRawTitle(a_Title.CreateJsonString(false)); } @@ -1258,12 +1258,12 @@ void cProtocol_1_8_0::SendSetTitle(const cCompositeChat & a_Title) void cProtocol_1_8_0::SendSetRawTitle(const AString & a_Title) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x45); // Title packet - Pkt.WriteVarInt32(0); // Set title + cPacketizer Pkt(*this, 0x45); // Title packet + Pkt.WriteVarInt32(0); // Set title - Pkt.WriteString(a_Title); + Pkt.WriteString(a_Title); } @@ -1272,15 +1272,15 @@ void cProtocol_1_8_0::SendSetRawTitle(const AString & a_Title) void cProtocol_1_8_0::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x29); // Sound Effect packet - Pkt.WriteString(a_SoundName); - Pkt.WriteBEInt32(static_cast<Int32>(a_X * 8.0)); - Pkt.WriteBEInt32(static_cast<Int32>(a_Y * 8.0)); - Pkt.WriteBEInt32(static_cast<Int32>(a_Z * 8.0)); - Pkt.WriteBEFloat(a_Volume); - Pkt.WriteBEUInt8(static_cast<Byte>(a_Pitch * 63)); + cPacketizer Pkt(*this, 0x29); // Sound Effect packet + Pkt.WriteString(a_SoundName); + Pkt.WriteBEInt32(static_cast<Int32>(a_X * 8.0)); + Pkt.WriteBEInt32(static_cast<Int32>(a_Y * 8.0)); + Pkt.WriteBEInt32(static_cast<Int32>(a_Z * 8.0)); + Pkt.WriteBEFloat(a_Volume); + Pkt.WriteBEUInt8(static_cast<Byte>(a_Pitch * 63)); } @@ -1289,13 +1289,13 @@ void cProtocol_1_8_0::SendSoundEffect(const AString & a_SoundName, double a_X, d void cProtocol_1_8_0::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x28); // Effect packet - Pkt.WriteBEInt32(static_cast<int>(a_EffectID)); - Pkt.WritePosition64(a_SrcX, a_SrcY, a_SrcZ); - Pkt.WriteBEInt32(a_Data); - Pkt.WriteBool(false); + cPacketizer Pkt(*this, 0x28); // Effect packet + Pkt.WriteBEInt32(static_cast<int>(a_EffectID)); + Pkt.WritePosition64(a_SrcX, a_SrcY, a_SrcZ); + Pkt.WriteBEInt32(a_Data); + Pkt.WriteBool(false); } @@ -1304,20 +1304,20 @@ void cProtocol_1_8_0::SendSoundParticleEffect(const EffectID a_EffectID, int a_S void cProtocol_1_8_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0e); // Spawn Object packet - Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); - Pkt.WriteBEUInt8(70); // Falling block - Pkt.WriteFPInt(a_FallingBlock.GetPosX()); - Pkt.WriteFPInt(a_FallingBlock.GetPosY()); - Pkt.WriteFPInt(a_FallingBlock.GetPosZ()); - Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); - Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); - Pkt.WriteBEInt32(static_cast<Int32>(a_FallingBlock.GetBlockType()) | (static_cast<Int32>(a_FallingBlock.GetBlockMeta()) << 12)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedZ() * 400)); + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet + Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); + Pkt.WriteBEUInt8(70); // Falling block + Pkt.WriteFPInt(a_FallingBlock.GetPosX()); + Pkt.WriteFPInt(a_FallingBlock.GetPosY()); + Pkt.WriteFPInt(a_FallingBlock.GetPosZ()); + Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); + Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); + Pkt.WriteBEInt32(static_cast<Int32>(a_FallingBlock.GetBlockType()) | (static_cast<Int32>(a_FallingBlock.GetBlockMeta()) << 12)); + Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedZ() * 400)); } @@ -1326,22 +1326,22 @@ void cProtocol_1_8_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet - Pkt.WriteVarInt32(a_Mob.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<Byte>(a_Mob.GetMobType())); - Pkt.WriteFPInt(a_Mob.GetPosX()); - Pkt.WriteFPInt(a_Mob.GetPosY()); - Pkt.WriteFPInt(a_Mob.GetPosZ()); - Pkt.WriteByteAngle(a_Mob.GetPitch()); - Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); - Pkt.WriteByteAngle(a_Mob.GetYaw()); - Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedZ() * 400)); - WriteEntityMetadata(Pkt, a_Mob); - Pkt.WriteBEUInt8(0x7f); // Metadata terminator + cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet + Pkt.WriteVarInt32(a_Mob.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<Byte>(a_Mob.GetMobType())); + Pkt.WriteFPInt(a_Mob.GetPosX()); + Pkt.WriteFPInt(a_Mob.GetPosY()); + Pkt.WriteFPInt(a_Mob.GetPosZ()); + Pkt.WriteByteAngle(a_Mob.GetPitch()); + Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); + Pkt.WriteByteAngle(a_Mob.GetYaw()); + Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedZ() * 400)); + WriteEntityMetadata(Pkt, a_Mob); + Pkt.WriteBEUInt8(0x7f); // Metadata terminator } @@ -1350,30 +1350,30 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob) void cProtocol_1_8_0::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) { - ASSERT(m_State == 3); // In game mode? - double PosX = a_Entity.GetPosX(); - double PosZ = a_Entity.GetPosZ(); - double Yaw = a_Entity.GetYaw(); - if (a_ObjectType == 71) - { - FixItemFramePositions(a_ObjectData, PosX, PosZ, Yaw); - } + ASSERT(m_State == 3); // In game mode? + double PosX = a_Entity.GetPosX(); + double PosZ = a_Entity.GetPosZ(); + double Yaw = a_Entity.GetYaw(); + if (a_ObjectType == 71) + { + FixItemFramePositions(a_ObjectData, PosX, PosZ, Yaw); + } - cPacketizer Pkt(*this, 0xe); // Spawn Object packet - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_ObjectType)); - Pkt.WriteFPInt(PosX); - Pkt.WriteFPInt(a_Entity.GetPosY()); - Pkt.WriteFPInt(PosZ); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteByteAngle(Yaw); - Pkt.WriteBEInt32(a_ObjectData); - if (a_ObjectData != 0) - { - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400)); - } + cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_ObjectType)); + Pkt.WriteFPInt(PosX); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(PosZ); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteByteAngle(Yaw); + Pkt.WriteBEInt32(a_ObjectData); + if (a_ObjectData != 0) + { + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400)); + } } @@ -1382,23 +1382,23 @@ void cProtocol_1_8_0::SendSpawnObject(const cEntity & a_Entity, char a_ObjectTyp void cProtocol_1_8_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0xe); // Spawn Object packet - Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast<UInt8>(a_VehicleType)); - Pkt.WriteFPInt(a_Vehicle.GetPosX()); - Pkt.WriteFPInt(a_Vehicle.GetPosY()); - Pkt.WriteFPInt(a_Vehicle.GetPosZ()); - Pkt.WriteByteAngle(a_Vehicle.GetPitch()); - Pkt.WriteByteAngle(a_Vehicle.GetYaw()); - Pkt.WriteBEInt32(a_VehicleSubType); - if (a_VehicleSubType != 0) - { - Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedZ() * 400)); - } + cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_VehicleType)); + Pkt.WriteFPInt(a_Vehicle.GetPosX()); + Pkt.WriteFPInt(a_Vehicle.GetPosY()); + Pkt.WriteFPInt(a_Vehicle.GetPosZ()); + Pkt.WriteByteAngle(a_Vehicle.GetPitch()); + Pkt.WriteByteAngle(a_Vehicle.GetYaw()); + Pkt.WriteBEInt32(a_VehicleSubType); + if (a_VehicleSubType != 0) + { + Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedZ() * 400)); + } } @@ -1407,20 +1407,20 @@ void cProtocol_1_8_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_Vehicle void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x37); - Pkt.WriteVarInt32(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only + cPacketizer Pkt(*this, 0x37); + Pkt.WriteVarInt32(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only - size_t Count = static_cast<size_t>(statCount); - for (size_t i = 0; i < Count; ++i) - { - StatValue Value = a_Manager.GetValue(static_cast<eStatistic>(i)); - const AString & StatName = cStatInfo::GetName(static_cast<eStatistic>(i)); + size_t Count = static_cast<size_t>(statCount); + for (size_t i = 0; i < Count; ++i) + { + StatValue Value = a_Manager.GetValue(static_cast<eStatistic>(i)); + const AString & StatName = cStatInfo::GetName(static_cast<eStatistic>(i)); - Pkt.WriteString(StatName); - Pkt.WriteVarInt32(static_cast<UInt32>(Value)); - } + Pkt.WriteString(StatName); + Pkt.WriteVarInt32(static_cast<UInt32>(Value)); + } } @@ -1429,15 +1429,15 @@ void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager) void cProtocol_1_8_0::SendTabCompletionResults(const AStringVector & a_Results) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet - Pkt.WriteVarInt32(static_cast<UInt32>(a_Results.size())); + cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet + Pkt.WriteVarInt32(static_cast<UInt32>(a_Results.size())); - for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr) - { - Pkt.WriteString(*itr); - } + for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr) + { + Pkt.WriteString(*itr); + } } @@ -1446,16 +1446,16 @@ void cProtocol_1_8_0::SendTabCompletionResults(const AStringVector & a_Results) void cProtocol_1_8_0::SendTeleportEntity(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x18); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteFPInt(a_Entity.GetPosX()); - Pkt.WriteFPInt(a_Entity.GetPosY()); - Pkt.WriteFPInt(a_Entity.GetPosZ()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(a_Entity.IsOnGround()); + cPacketizer Pkt(*this, 0x18); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(a_Entity.IsOnGround()); } @@ -1464,14 +1464,14 @@ void cProtocol_1_8_0::SendTeleportEntity(const cEntity & a_Entity) void cProtocol_1_8_0::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet - Pkt.WriteVarInt32(0); // EntityID = 0, always - Pkt.WriteBEUInt8(1); // Type = Thunderbolt - Pkt.WriteFPInt(a_BlockX); - Pkt.WriteFPInt(a_BlockY); - Pkt.WriteFPInt(a_BlockZ); + cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet + Pkt.WriteVarInt32(0); // EntityID = 0, always + Pkt.WriteBEUInt8(1); // Type = Thunderbolt + Pkt.WriteFPInt(a_BlockX); + Pkt.WriteFPInt(a_BlockY); + Pkt.WriteFPInt(a_BlockZ); } @@ -1480,14 +1480,14 @@ void cProtocol_1_8_0::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) void cProtocol_1_8_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x45); // Title packet - Pkt.WriteVarInt32(2); // Set title display times + cPacketizer Pkt(*this, 0x45); // Title packet + Pkt.WriteVarInt32(2); // Set title display times - Pkt.WriteBEInt32(a_FadeInTicks); - Pkt.WriteBEInt32(a_DisplayTicks); - Pkt.WriteBEInt32(a_FadeOutTicks); + Pkt.WriteBEInt32(a_FadeInTicks); + Pkt.WriteBEInt32(a_DisplayTicks); + Pkt.WriteBEInt32(a_FadeOutTicks); } @@ -1496,16 +1496,16 @@ void cProtocol_1_8_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { - ASSERT(m_State == 3); // In game mode? - if (!a_DoDaylightCycle) - { - // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. - a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); - } + ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } - cPacketizer Pkt(*this, 0x03); - Pkt.WriteBEInt64(a_WorldAge); - Pkt.WriteBEInt64(a_TimeOfDay); + cPacketizer Pkt(*this, 0x03); + Pkt.WriteBEInt64(a_WorldAge); + Pkt.WriteBEInt64(a_TimeOfDay); } @@ -1514,14 +1514,14 @@ void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a void cProtocol_1_8_0::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x21); // Chunk Data packet - Pkt.WriteBEInt32(a_ChunkX); - Pkt.WriteBEInt32(a_ChunkZ); - Pkt.WriteBool(true); - Pkt.WriteBEInt16(0); // Primary bitmap - Pkt.WriteVarInt32(0); // Data size + cPacketizer Pkt(*this, 0x21); // Chunk Data packet + Pkt.WriteBEInt32(a_ChunkX); + Pkt.WriteBEInt32(a_ChunkZ); + Pkt.WriteBool(true); + Pkt.WriteBEInt16(0); // Primary bitmap + Pkt.WriteVarInt32(0); // Data size } @@ -1529,24 +1529,24 @@ void cProtocol_1_8_0::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cProtocol_1_8_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x35); // Update tile entity packet - Pkt.WritePosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); + cPacketizer Pkt(*this, 0x35); // Update tile entity packet + Pkt.WritePosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); - Byte Action = 0; - switch (a_BlockEntity.GetBlockType()) - { - case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing - case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text - case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity - case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity - case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot - default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; - } - Pkt.WriteBEUInt8(Action); + Byte Action = 0; + switch (a_BlockEntity.GetBlockType()) + { + case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing + case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text + case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity + case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity + case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot + default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; + } + Pkt.WriteBEUInt8(Action); - WriteBlockEntity(Pkt, a_BlockEntity); + WriteBlockEntity(Pkt, a_BlockEntity); } @@ -1555,19 +1555,19 @@ void cProtocol_1_8_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) void cProtocol_1_8_0::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x33); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + cPacketizer Pkt(*this, 0x33); + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); - Json::StyledWriter JsonWriter; - AString Lines[] = { a_Line1, a_Line2, a_Line3, a_Line4 }; - for (size_t i = 0; i < ARRAYCOUNT(Lines); i++) - { - Json::Value RootValue; - RootValue["text"] = Lines[i]; - Pkt.WriteString(JsonWriter.write(RootValue).c_str()); - } + Json::StyledWriter JsonWriter; + AString Lines[] = { a_Line1, a_Line2, a_Line3, a_Line4 }; + for (size_t i = 0; i < ARRAYCOUNT(Lines); i++) + { + Json::Value RootValue; + RootValue["text"] = Lines[i]; + Pkt.WriteString(JsonWriter.write(RootValue).c_str()); + } } @@ -1576,11 +1576,11 @@ void cProtocol_1_8_0::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, c void cProtocol_1_8_0::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0a); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + cPacketizer Pkt(*this, 0x0a); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); } @@ -1589,15 +1589,15 @@ void cProtocol_1_8_0::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_B void cProtocol_1_8_0::SendWeather(eWeather a_Weather) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - { - cPacketizer Pkt(*this, 0x2b); // Change Game State packet - Pkt.WriteBEUInt8((a_Weather == wSunny) ? 1 : 2); // End rain / begin rain - Pkt.WriteBEFloat(0); // Unused for weather - } + { + cPacketizer Pkt(*this, 0x2b); // Change Game State packet + Pkt.WriteBEUInt8((a_Weather == wSunny) ? 1 : 2); // End rain / begin rain + Pkt.WriteBEFloat(0); // Unused for weather + } - // TODO: Fade effect, somehow + // TODO: Fade effect, somehow } @@ -1606,17 +1606,17 @@ void cProtocol_1_8_0::SendWeather(eWeather a_Weather) void cProtocol_1_8_0::SendWholeInventory(const cWindow & a_Window) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x30); // Window Items packet - Pkt.WriteBEInt8(a_Window.GetWindowID()); - Pkt.WriteBEInt16(static_cast<Int16>(a_Window.GetNumSlots())); - cItems Slots; - a_Window.GetSlots(*(m_Client->GetPlayer()), Slots); - for (cItems::const_iterator itr = Slots.begin(), end = Slots.end(); itr != end; ++itr) - { - WriteItem(Pkt, *itr); - } // for itr - Slots[] + cPacketizer Pkt(*this, 0x30); // Window Items packet + Pkt.WriteBEInt8(a_Window.GetWindowID()); + Pkt.WriteBEInt16(static_cast<Int16>(a_Window.GetNumSlots())); + cItems Slots; + a_Window.GetSlots(*(m_Client->GetPlayer()), Slots); + for (cItems::const_iterator itr = Slots.begin(), end = Slots.end(); itr != end; ++itr) + { + WriteItem(Pkt, *itr); + } // for itr - Slots[] } @@ -1625,10 +1625,10 @@ void cProtocol_1_8_0::SendWholeInventory(const cWindow & a_Window) void cProtocol_1_8_0::SendWindowClose(const cWindow & a_Window) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x2e); - Pkt.WriteBEInt8(a_Window.GetWindowID()); + cPacketizer Pkt(*this, 0x2e); + Pkt.WriteBEInt8(a_Window.GetWindowID()); } @@ -1637,39 +1637,39 @@ void cProtocol_1_8_0::SendWindowClose(const cWindow & a_Window) void cProtocol_1_8_0::SendWindowOpen(const cWindow & a_Window) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - if (a_Window.GetWindowType() < 0) - { - // Do not send this packet for player inventory windows - return; - } + if (a_Window.GetWindowType() < 0) + { + // Do not send this packet for player inventory windows + return; + } - cPacketizer Pkt(*this, 0x2d); - Pkt.WriteBEInt8(a_Window.GetWindowID()); - Pkt.WriteString(a_Window.GetWindowTypeName()); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_Window.GetWindowTitle().c_str())); + cPacketizer Pkt(*this, 0x2d); + Pkt.WriteBEInt8(a_Window.GetWindowID()); + Pkt.WriteString(a_Window.GetWindowTypeName()); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_Window.GetWindowTitle().c_str())); - switch (a_Window.GetWindowType()) - { - case cWindow::wtWorkbench: - case cWindow::wtEnchantment: - case cWindow::wtAnvil: - { - Pkt.WriteBEInt8(0); - break; - } - default: - { - Pkt.WriteBEInt8(static_cast<Int8>(a_Window.GetNumNonInventorySlots())); - break; - } - } + switch (a_Window.GetWindowType()) + { + case cWindow::wtWorkbench: + case cWindow::wtEnchantment: + case cWindow::wtAnvil: + { + Pkt.WriteBEInt8(0); + break; + } + default: + { + Pkt.WriteBEInt8(static_cast<Int8>(a_Window.GetNumNonInventorySlots())); + break; + } + } - if (a_Window.GetWindowType() == cWindow::wtAnimalChest) - { - Pkt.WriteBEInt32(0); // TODO: The animal's EntityID - } + if (a_Window.GetWindowType() == cWindow::wtAnimalChest) + { + Pkt.WriteBEInt32(0); // TODO: The animal's EntityID + } } @@ -1678,12 +1678,12 @@ void cProtocol_1_8_0::SendWindowOpen(const cWindow & a_Window) void cProtocol_1_8_0::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x31); // Window Property packet - Pkt.WriteBEInt8(a_Window.GetWindowID()); - Pkt.WriteBEInt16(a_Property); - Pkt.WriteBEInt16(a_Value); + cPacketizer Pkt(*this, 0x31); // Window Property packet + Pkt.WriteBEInt8(a_Window.GetWindowID()); + Pkt.WriteBEInt16(a_Property); + Pkt.WriteBEInt16(a_Value); } @@ -1692,41 +1692,41 @@ void cProtocol_1_8_0::SendWindowProperty(const cWindow & a_Window, short a_Prope bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_CompressedData) { - // Compress the data: - char CompressedData[MAX_COMPRESSED_PACKET_LEN]; + // Compress the data: + char CompressedData[MAX_COMPRESSED_PACKET_LEN]; - uLongf CompressedSize = compressBound(static_cast<uLongf>(a_Packet.size())); - if (CompressedSize >= MAX_COMPRESSED_PACKET_LEN) - { - ASSERT(!"Too high packet size."); - return false; - } + uLongf CompressedSize = compressBound(static_cast<uLongf>(a_Packet.size())); + if (CompressedSize >= MAX_COMPRESSED_PACKET_LEN) + { + ASSERT(!"Too high packet size."); + return false; + } - int Status = compress2( - reinterpret_cast<Bytef *>(CompressedData), &CompressedSize, - reinterpret_cast<const Bytef *>(a_Packet.data()), static_cast<uLongf>(a_Packet.size()), Z_DEFAULT_COMPRESSION - ); - if (Status != Z_OK) - { - return false; - } + int Status = compress2( + reinterpret_cast<Bytef *>(CompressedData), &CompressedSize, + reinterpret_cast<const Bytef *>(a_Packet.data()), static_cast<uLongf>(a_Packet.size()), Z_DEFAULT_COMPRESSION + ); + if (Status != Z_OK) + { + return false; + } - AString LengthData; - cByteBuffer Buffer(20); - Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size())); - Buffer.ReadAll(LengthData); - Buffer.CommitRead(); + AString LengthData; + cByteBuffer Buffer(20); + Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size())); + Buffer.ReadAll(LengthData); + Buffer.CommitRead(); - Buffer.WriteVarInt32(static_cast<UInt32>(CompressedSize + LengthData.size())); - Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size())); - Buffer.ReadAll(LengthData); - Buffer.CommitRead(); + Buffer.WriteVarInt32(static_cast<UInt32>(CompressedSize + LengthData.size())); + Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size())); + Buffer.ReadAll(LengthData); + Buffer.CommitRead(); - a_CompressedData.clear(); - a_CompressedData.reserve(LengthData.size() + CompressedSize); - a_CompressedData.append(LengthData.data(), LengthData.size()); - a_CompressedData.append(CompressedData, CompressedSize); - return true; + a_CompressedData.clear(); + a_CompressedData.reserve(LengthData.size() + CompressedSize); + a_CompressedData.append(LengthData.data(), LengthData.size()); + a_CompressedData.append(CompressedData, CompressedSize); + return true; } @@ -1735,70 +1735,70 @@ bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_Compr int cProtocol_1_8_0::GetParticleID(const AString & a_ParticleName) { - static std::map<AString, int> ParticleMap; - if (ParticleMap.empty()) - { - // Initialize the ParticleMap: - ParticleMap["explode"] = 0; - ParticleMap["largeexplode"] = 1; - ParticleMap["hugeexplosion"] = 2; - ParticleMap["fireworksspark"] = 3; - ParticleMap["bubble"] = 4; - ParticleMap["splash"] = 5; - ParticleMap["wake"] = 6; - ParticleMap["suspended"] = 7; - ParticleMap["depthsuspend"] = 8; - ParticleMap["crit"] = 9; - ParticleMap["magiccrit"] = 10; - ParticleMap["smoke"] = 11; - ParticleMap["largesmoke"] = 12; - ParticleMap["spell"] = 13; - ParticleMap["instantspell"] = 14; - ParticleMap["mobspell"] = 15; - ParticleMap["mobspellambient"] = 16; - ParticleMap["witchmagic"] = 17; - ParticleMap["dripwater"] = 18; - ParticleMap["driplava"] = 19; - ParticleMap["angryvillager"] = 20; - ParticleMap["happyvillager"] = 21; - ParticleMap["townaura"] = 22; - ParticleMap["note"] = 23; - ParticleMap["portal"] = 24; - ParticleMap["enchantmenttable"] = 25; - ParticleMap["flame"] = 26; - ParticleMap["lava"] = 27; - ParticleMap["footstep"] = 28; - ParticleMap["cloud"] = 29; - ParticleMap["reddust"] = 30; - ParticleMap["snowballpoof"] = 31; - ParticleMap["snowshovel"] = 32; - ParticleMap["slime"] = 33; - ParticleMap["heart"] = 34; - ParticleMap["barrier"] = 35; - ParticleMap["iconcrack"] = 36; - ParticleMap["blockcrack"] = 37; - ParticleMap["blockdust"] = 38; - ParticleMap["droplet"] = 39; - ParticleMap["take"] = 40; - ParticleMap["mobappearance"] = 41; - ParticleMap["dragonbreath"] = 42; - ParticleMap["endrod"] = 43; - ParticleMap["damageindicator"] = 44; - ParticleMap["sweepattack"] = 45; - ParticleMap["fallingdust"] = 46; - ParticleMap["totem"] = 47; - ParticleMap["spit"] = 48; - } - - AString ParticleName = StrToLower(a_ParticleName); - if (ParticleMap.find(ParticleName) == ParticleMap.end()) - { - LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); - ASSERT(!"Unknown particle"); - return 0; - } - - return ParticleMap[ParticleName]; + static std::map<AString, int> ParticleMap; + if (ParticleMap.empty()) + { + // Initialize the ParticleMap: + ParticleMap["explode"] = 0; + ParticleMap["largeexplode"] = 1; + ParticleMap["hugeexplosion"] = 2; + ParticleMap["fireworksspark"] = 3; + ParticleMap["bubble"] = 4; + ParticleMap["splash"] = 5; + ParticleMap["wake"] = 6; + ParticleMap["suspended"] = 7; + ParticleMap["depthsuspend"] = 8; + ParticleMap["crit"] = 9; + ParticleMap["magiccrit"] = 10; + ParticleMap["smoke"] = 11; + ParticleMap["largesmoke"] = 12; + ParticleMap["spell"] = 13; + ParticleMap["instantspell"] = 14; + ParticleMap["mobspell"] = 15; + ParticleMap["mobspellambient"] = 16; + ParticleMap["witchmagic"] = 17; + ParticleMap["dripwater"] = 18; + ParticleMap["driplava"] = 19; + ParticleMap["angryvillager"] = 20; + ParticleMap["happyvillager"] = 21; + ParticleMap["townaura"] = 22; + ParticleMap["note"] = 23; + ParticleMap["portal"] = 24; + ParticleMap["enchantmenttable"] = 25; + ParticleMap["flame"] = 26; + ParticleMap["lava"] = 27; + ParticleMap["footstep"] = 28; + ParticleMap["cloud"] = 29; + ParticleMap["reddust"] = 30; + ParticleMap["snowballpoof"] = 31; + ParticleMap["snowshovel"] = 32; + ParticleMap["slime"] = 33; + ParticleMap["heart"] = 34; + ParticleMap["barrier"] = 35; + ParticleMap["iconcrack"] = 36; + ParticleMap["blockcrack"] = 37; + ParticleMap["blockdust"] = 38; + ParticleMap["droplet"] = 39; + ParticleMap["take"] = 40; + ParticleMap["mobappearance"] = 41; + ParticleMap["dragonbreath"] = 42; + ParticleMap["endrod"] = 43; + ParticleMap["damageindicator"] = 44; + ParticleMap["sweepattack"] = 45; + ParticleMap["fallingdust"] = 46; + ParticleMap["totem"] = 47; + ParticleMap["spit"] = 48; + } + + AString ParticleName = StrToLower(a_ParticleName); + if (ParticleMap.find(ParticleName) == ParticleMap.end()) + { + LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); + ASSERT(!"Unknown particle"); + return 0; + } + + return ParticleMap[ParticleName]; } @@ -1807,33 +1807,33 @@ int cProtocol_1_8_0::GetParticleID(const AString & a_ParticleName) void cProtocol_1_8_0::FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw) { - switch (a_ObjectData) - { - case 0: - { - a_PosZ += 1; - a_Yaw = 0; - break; - } - case 1: - { - a_PosX -= 1; - a_Yaw = 90; - break; - } - case 2: - { - a_PosZ -= 1; - a_Yaw = 180; - break; - } - case 3: - { - a_PosX += 1; - a_Yaw = 270; - break; - } - } + switch (a_ObjectData) + { + case 0: + { + a_PosZ += 1; + a_Yaw = 0; + break; + } + case 1: + { + a_PosX -= 1; + a_Yaw = 90; + break; + } + case 2: + { + a_PosZ -= 1; + a_Yaw = 180; + break; + } + case 3: + { + a_PosX += 1; + a_Yaw = 270; + break; + } + } } @@ -1842,194 +1842,194 @@ void cProtocol_1_8_0::FixItemFramePositions(int a_ObjectData, double & a_PosX, d void cProtocol_1_8_0::AddReceivedData(const char * a_Data, size_t a_Size) { - // Write the incoming data into the comm log file: - if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) - { - if (m_ReceivedData.GetReadableSpace() > 0) - { - AString AllData; - size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); - m_ReceivedData.ReadAll(AllData); - m_ReceivedData.ResetRead(); - m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); - ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); - AString Hex; - CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("Incoming data, " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") unparsed bytes already present in buffer:\n%s\n", - AllData.size(), AllData.size(), Hex.c_str() - ); - } - AString Hex; - CreateHexDump(Hex, a_Data, a_Size, 16); - m_CommLogFile.Printf("Incoming data: %u (0x%x) bytes: \n%s\n", - static_cast<unsigned>(a_Size), static_cast<unsigned>(a_Size), Hex.c_str() - ); - m_CommLogFile.Flush(); - } - - if (!m_ReceivedData.Write(a_Data, a_Size)) - { - // Too much data in the incoming queue, report to caller: - m_Client->PacketBufferFull(); - return; - } - - // Handle all complete packets: - for (;;) - { - UInt32 PacketLen; - if (!m_ReceivedData.ReadVarInt(PacketLen)) - { - // Not enough data - m_ReceivedData.ResetRead(); - break; - } - if (!m_ReceivedData.CanReadBytes(PacketLen)) - { - // The full packet hasn't been received yet - m_ReceivedData.ResetRead(); - break; - } - - // Check packet for compression: - UInt32 UncompressedSize = 0; - AString UncompressedData; - if (m_State == 3) - { - UInt32 NumBytesRead = static_cast<UInt32>(m_ReceivedData.GetReadableSpace()); - - if (!m_ReceivedData.ReadVarInt(UncompressedSize)) - { - m_Client->Kick("Compression packet incomplete"); - return; - } - - NumBytesRead -= static_cast<UInt32>(m_ReceivedData.GetReadableSpace()); // How many bytes has the UncompressedSize taken up? - ASSERT(PacketLen > NumBytesRead); - PacketLen -= NumBytesRead; - - if (UncompressedSize > 0) - { - // Decompress the data: - AString CompressedData; - VERIFY(m_ReceivedData.ReadString(CompressedData, PacketLen)); - if (InflateString(CompressedData.data(), PacketLen, UncompressedData) != Z_OK) - { - m_Client->Kick("Compression failure"); - return; - } - PacketLen = static_cast<UInt32>(UncompressedData.size()); - if (PacketLen != UncompressedSize) - { - m_Client->Kick("Wrong uncompressed packet size given"); - return; - } - } - } - - // Move the packet payload to a separate cByteBuffer, bb: - cByteBuffer bb(PacketLen + 1); - if (UncompressedSize == 0) - { - // No compression was used, move directly - VERIFY(m_ReceivedData.ReadToByteBuffer(bb, static_cast<size_t>(PacketLen))); - } - else - { - // Compression was used, move the uncompressed data: - VERIFY(bb.Write(UncompressedData.data(), UncompressedData.size())); - } - m_ReceivedData.CommitRead(); - - UInt32 PacketType; - if (!bb.ReadVarInt(PacketType)) - { - // Not enough data - break; - } - - // Write one NUL extra, so that we can detect over-reads - bb.Write("\0", 1); - - // Log the packet info into the comm log file: - if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) - { - AString PacketData; - bb.ReadAll(PacketData); - bb.ResetRead(); - bb.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again - ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read - PacketData.resize(PacketData.size() - 1); - AString PacketDataHex; - CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); - m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n", - PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() - ); - } - - if (!HandlePacket(bb, PacketType)) - { - // Unknown packet, already been reported, but without the length. Log the length here: - LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, PacketLen); - - #ifdef _DEBUG - // Dump the packet contents into the log: - bb.ResetRead(); - AString Packet; - bb.ReadAll(Packet); - Packet.resize(Packet.size() - 1); // Drop the final NUL pushed there for over-read detection - AString Out; - CreateHexDump(Out, Packet.data(), Packet.size(), 24); - LOGD("Packet contents:\n%s", Out.c_str()); - #endif // _DEBUG - - // Put a message in the comm log: - if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) - { - m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); - } - - return; - } - - // The packet should have 1 byte left in the buffer - the NUL we had added - if (bb.GetReadableSpace() != 1) - { - // Read more or less than packet length, report as error - LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", - PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen - ); - - // Put a message in the comm log: - if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) - { - m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got " SIZE_T_FMT " left) ^^^^^^\n\n\n", - 1, bb.GetReadableSpace() - ); - m_CommLogFile.Flush(); - } - - ASSERT(!"Read wrong number of bytes!"); - m_Client->PacketError(PacketType); - } - } // for (ever) - - // Log any leftover bytes into the logfile: - if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0) && m_CommLogFile.IsOpen()) - { - AString AllData; - size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); - m_ReceivedData.ReadAll(AllData); - m_ReceivedData.ResetRead(); - m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); - ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); - AString Hex; - CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("There are " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") bytes of non-parse-able data left in the buffer:\n%s", - m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() - ); - m_CommLogFile.Flush(); - } + // Write the incoming data into the comm log file: + if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) + { + if (m_ReceivedData.GetReadableSpace() > 0) + { + AString AllData; + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadAll(AllData); + m_ReceivedData.ResetRead(); + m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); + ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); + AString Hex; + CreateHexDump(Hex, AllData.data(), AllData.size(), 16); + m_CommLogFile.Printf("Incoming data, " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") unparsed bytes already present in buffer:\n%s\n", + AllData.size(), AllData.size(), Hex.c_str() + ); + } + AString Hex; + CreateHexDump(Hex, a_Data, a_Size, 16); + m_CommLogFile.Printf("Incoming data: %u (0x%x) bytes: \n%s\n", + static_cast<unsigned>(a_Size), static_cast<unsigned>(a_Size), Hex.c_str() + ); + m_CommLogFile.Flush(); + } + + if (!m_ReceivedData.Write(a_Data, a_Size)) + { + // Too much data in the incoming queue, report to caller: + m_Client->PacketBufferFull(); + return; + } + + // Handle all complete packets: + for (;;) + { + UInt32 PacketLen; + if (!m_ReceivedData.ReadVarInt(PacketLen)) + { + // Not enough data + m_ReceivedData.ResetRead(); + break; + } + if (!m_ReceivedData.CanReadBytes(PacketLen)) + { + // The full packet hasn't been received yet + m_ReceivedData.ResetRead(); + break; + } + + // Check packet for compression: + UInt32 UncompressedSize = 0; + AString UncompressedData; + if (m_State == 3) + { + UInt32 NumBytesRead = static_cast<UInt32>(m_ReceivedData.GetReadableSpace()); + + if (!m_ReceivedData.ReadVarInt(UncompressedSize)) + { + m_Client->Kick("Compression packet incomplete"); + return; + } + + NumBytesRead -= static_cast<UInt32>(m_ReceivedData.GetReadableSpace()); // How many bytes has the UncompressedSize taken up? + ASSERT(PacketLen > NumBytesRead); + PacketLen -= NumBytesRead; + + if (UncompressedSize > 0) + { + // Decompress the data: + AString CompressedData; + VERIFY(m_ReceivedData.ReadString(CompressedData, PacketLen)); + if (InflateString(CompressedData.data(), PacketLen, UncompressedData) != Z_OK) + { + m_Client->Kick("Compression failure"); + return; + } + PacketLen = static_cast<UInt32>(UncompressedData.size()); + if (PacketLen != UncompressedSize) + { + m_Client->Kick("Wrong uncompressed packet size given"); + return; + } + } + } + + // Move the packet payload to a separate cByteBuffer, bb: + cByteBuffer bb(PacketLen + 1); + if (UncompressedSize == 0) + { + // No compression was used, move directly + VERIFY(m_ReceivedData.ReadToByteBuffer(bb, static_cast<size_t>(PacketLen))); + } + else + { + // Compression was used, move the uncompressed data: + VERIFY(bb.Write(UncompressedData.data(), UncompressedData.size())); + } + m_ReceivedData.CommitRead(); + + UInt32 PacketType; + if (!bb.ReadVarInt(PacketType)) + { + // Not enough data + break; + } + + // Write one NUL extra, so that we can detect over-reads + bb.Write("\0", 1); + + // Log the packet info into the comm log file: + if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) + { + AString PacketData; + bb.ReadAll(PacketData); + bb.ResetRead(); + bb.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again + ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read + PacketData.resize(PacketData.size() - 1); + AString PacketDataHex; + CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); + m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n", + PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() + ); + } + + if (!HandlePacket(bb, PacketType)) + { + // Unknown packet, already been reported, but without the length. Log the length here: + LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, PacketLen); + + #ifdef _DEBUG + // Dump the packet contents into the log: + bb.ResetRead(); + AString Packet; + bb.ReadAll(Packet); + Packet.resize(Packet.size() - 1); // Drop the final NUL pushed there for over-read detection + AString Out; + CreateHexDump(Out, Packet.data(), Packet.size(), 24); + LOGD("Packet contents:\n%s", Out.c_str()); + #endif // _DEBUG + + // Put a message in the comm log: + if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) + { + m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); + } + + return; + } + + // The packet should have 1 byte left in the buffer - the NUL we had added + if (bb.GetReadableSpace() != 1) + { + // Read more or less than packet length, report as error + LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", + PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen + ); + + // Put a message in the comm log: + if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) + { + m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got " SIZE_T_FMT " left) ^^^^^^\n\n\n", + 1, bb.GetReadableSpace() + ); + m_CommLogFile.Flush(); + } + + ASSERT(!"Read wrong number of bytes!"); + m_Client->PacketError(PacketType); + } + } // for (ever) + + // Log any leftover bytes into the logfile: + if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0) && m_CommLogFile.IsOpen()) + { + AString AllData; + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadAll(AllData); + m_ReceivedData.ResetRead(); + m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); + ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); + AString Hex; + CreateHexDump(Hex, AllData.data(), AllData.size(), 16); + m_CommLogFile.Printf("There are " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") bytes of non-parse-able data left in the buffer:\n%s", + m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() + ); + m_CommLogFile.Flush(); + } } @@ -2037,85 +2037,85 @@ void cProtocol_1_8_0::AddReceivedData(const char * a_Data, size_t a_Size) bool cProtocol_1_8_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) { - switch (m_State) - { - case 1: - { - // Status - switch (a_PacketType) - { - case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return true; - case 0x01: HandlePacketStatusPing (a_ByteBuffer); return true; - } - break; - } - - case 2: - { - // Login - switch (a_PacketType) - { - case 0x00: HandlePacketLoginStart (a_ByteBuffer); return true; - case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return true; - } - break; - } - - case 3: - { - // Game - switch (a_PacketType) - { - case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return true; - case 0x01: HandlePacketChatMessage (a_ByteBuffer); return true; - case 0x02: HandlePacketUseEntity (a_ByteBuffer); return true; - case 0x03: HandlePacketPlayer (a_ByteBuffer); return true; - case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return true; - case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return true; - case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return true; - case 0x07: HandlePacketBlockDig (a_ByteBuffer); return true; - case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return true; - case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return true; - case 0x0a: HandlePacketAnimation (a_ByteBuffer); return true; - case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return true; - case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return true; - case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return true; - case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true; - case 0x0f: // Confirm transaction - not used in MCS - case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true; - case 0x11: HandlePacketEnchantItem (a_ByteBuffer); return true; - case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true; - case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true; - case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true; - case 0x15: HandlePacketClientSettings (a_ByteBuffer); return true; - case 0x16: HandlePacketClientStatus (a_ByteBuffer); return true; - case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return true; - case 0x18: HandlePacketSpectate (a_ByteBuffer); return true; - } - break; - } - default: - { - // Received a packet in an unknown state, report: - LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); - - // Cannot kick the client - we don't know this state and thus the packet number for the kick packet - - // Switch to a state when all further packets are silently ignored: - m_State = 255; - return false; - } - case 255: - { - // This is the state used for "not processing packets anymore" when we receive a bad packet from a client. - // Do not output anything (the caller will do that for us), just return failure - return false; - } - } // switch (m_State) - - // Unknown packet type, report to the ClientHandle: - m_Client->PacketUnknown(a_PacketType); - return false; + switch (m_State) + { + case 1: + { + // Status + switch (a_PacketType) + { + case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return true; + case 0x01: HandlePacketStatusPing (a_ByteBuffer); return true; + } + break; + } + + case 2: + { + // Login + switch (a_PacketType) + { + case 0x00: HandlePacketLoginStart (a_ByteBuffer); return true; + case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return true; + } + break; + } + + case 3: + { + // Game + switch (a_PacketType) + { + case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return true; + case 0x01: HandlePacketChatMessage (a_ByteBuffer); return true; + case 0x02: HandlePacketUseEntity (a_ByteBuffer); return true; + case 0x03: HandlePacketPlayer (a_ByteBuffer); return true; + case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return true; + case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return true; + case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return true; + case 0x07: HandlePacketBlockDig (a_ByteBuffer); return true; + case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return true; + case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return true; + case 0x0a: HandlePacketAnimation (a_ByteBuffer); return true; + case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return true; + case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return true; + case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return true; + case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true; + case 0x0f: // Confirm transaction - not used in MCS + case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true; + case 0x11: HandlePacketEnchantItem (a_ByteBuffer); return true; + case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true; + case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true; + case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true; + case 0x15: HandlePacketClientSettings (a_ByteBuffer); return true; + case 0x16: HandlePacketClientStatus (a_ByteBuffer); return true; + case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return true; + case 0x18: HandlePacketSpectate (a_ByteBuffer); return true; + } + break; + } + default: + { + // Received a packet in an unknown state, report: + LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); + + // Cannot kick the client - we don't know this state and thus the packet number for the kick packet + + // Switch to a state when all further packets are silently ignored: + m_State = 255; + return false; + } + case 255: + { + // This is the state used for "not processing packets anymore" when we receive a bad packet from a client. + // Do not output anything (the caller will do that for us), just return failure + return false; + } + } // switch (m_State) + + // Unknown packet type, report to the ClientHandle: + m_Client->PacketUnknown(a_PacketType); + return false; } @@ -2124,10 +2124,10 @@ bool cProtocol_1_8_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTy void cProtocol_1_8_0::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp); + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp); - cPacketizer Pkt(*this, 0x01); // Ping packet - Pkt.WriteBEInt64(Timestamp); + cPacketizer Pkt(*this, 0x01); // Ping packet + Pkt.WriteBEInt64(Timestamp); } @@ -2136,43 +2136,43 @@ void cProtocol_1_8_0::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) { - cServer * Server = cRoot::Get()->GetServer(); - AString ServerDescription = Server->GetDescription(); - auto NumPlayers = static_cast<signed>(Server->GetNumPlayers()); - auto MaxPlayers = static_cast<signed>(Server->GetMaxPlayers()); - AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + auto NumPlayers = static_cast<signed>(Server->GetNumPlayers()); + auto MaxPlayers = static_cast<signed>(Server->GetMaxPlayers()); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); - // Version: - Json::Value Version; - Version["name"] = "Cuberite 1.8"; - Version["protocol"] = 47; + // Version: + Json::Value Version; + Version["name"] = "Cuberite 1.8"; + Version["protocol"] = 47; - // Players: - Json::Value Players; - Players["online"] = NumPlayers; - Players["max"] = MaxPlayers; - // TODO: Add "sample" + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" - // Description: - Json::Value Description; - Description["text"] = ServerDescription.c_str(); + // Description: + Json::Value Description; + Description["text"] = ServerDescription.c_str(); - // Create the response: - Json::Value ResponseValue; - ResponseValue["version"] = Version; - ResponseValue["players"] = Players; - ResponseValue["description"] = Description; - if (!Favicon.empty()) - { - ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); - } + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } - Json::FastWriter Writer; - AString Response = Writer.write(ResponseValue); + Json::FastWriter Writer; + AString Response = Writer.write(ResponseValue); - cPacketizer Pkt(*this, 0x00); // Response packet - Pkt.WriteString(Response); + cPacketizer Pkt(*this, 0x00); // Response packet + Pkt.WriteString(Response); } @@ -2181,61 +2181,61 @@ void cProtocol_1_8_0::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) { - UInt32 EncKeyLength, EncNonceLength; - if (!a_ByteBuffer.ReadVarInt(EncKeyLength)) - { - return; - } - AString EncKey; - if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) - { - return; - } - if (!a_ByteBuffer.ReadVarInt(EncNonceLength)) - { - return; - } - AString EncNonce; - if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) - { - return; - } - if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) - { - LOGD("Too long encryption"); - m_Client->Kick("Hacked client"); - return; - } - - // Decrypt EncNonce using privkey - cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); - UInt32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; - int res = rsaDecryptor.Decrypt(reinterpret_cast<const Byte *>(EncNonce.data()), EncNonce.size(), reinterpret_cast<Byte *>(DecryptedNonce), sizeof(DecryptedNonce)); - if (res != 4) - { - LOGD("Bad nonce length: got %d, exp %d", res, 4); - m_Client->Kick("Hacked client"); - return; - } - if (ntohl(DecryptedNonce[0]) != static_cast<unsigned>(reinterpret_cast<uintptr_t>(this))) - { - LOGD("Bad nonce value"); - m_Client->Kick("Hacked client"); - return; - } - - // Decrypt the symmetric encryption key using privkey: - Byte DecryptedKey[MAX_ENC_LEN]; - res = rsaDecryptor.Decrypt(reinterpret_cast<const Byte *>(EncKey.data()), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); - if (res != 16) - { - LOGD("Bad key length"); - m_Client->Kick("Hacked client"); - return; - } - - StartEncryption(DecryptedKey); - m_Client->HandleLogin(m_Client->GetUsername()); + UInt32 EncKeyLength, EncNonceLength; + if (!a_ByteBuffer.ReadVarInt(EncKeyLength)) + { + return; + } + AString EncKey; + if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) + { + return; + } + if (!a_ByteBuffer.ReadVarInt(EncNonceLength)) + { + return; + } + AString EncNonce; + if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) + { + return; + } + if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) + { + LOGD("Too long encryption"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt EncNonce using privkey + cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); + UInt32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; + int res = rsaDecryptor.Decrypt(reinterpret_cast<const Byte *>(EncNonce.data()), EncNonce.size(), reinterpret_cast<Byte *>(DecryptedNonce), sizeof(DecryptedNonce)); + if (res != 4) + { + LOGD("Bad nonce length: got %d, exp %d", res, 4); + m_Client->Kick("Hacked client"); + return; + } + if (ntohl(DecryptedNonce[0]) != static_cast<unsigned>(reinterpret_cast<uintptr_t>(this))) + { + LOGD("Bad nonce value"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt the symmetric encryption key using privkey: + Byte DecryptedKey[MAX_ENC_LEN]; + res = rsaDecryptor.Decrypt(reinterpret_cast<const Byte *>(EncKey.data()), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); + if (res != 16) + { + LOGD("Bad key length"); + m_Client->Kick("Hacked client"); + return; + } + + StartEncryption(DecryptedKey); + m_Client->HandleLogin(m_Client->GetUsername()); } @@ -2244,35 +2244,35 @@ void cProtocol_1_8_0::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBu void cProtocol_1_8_0::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) { - AString Username; - if (!a_ByteBuffer.ReadVarUTF8String(Username)) - { - m_Client->Kick("Bad username"); - return; - } + AString Username; + if (!a_ByteBuffer.ReadVarUTF8String(Username)) + { + m_Client->Kick("Bad username"); + return; + } - if (!m_Client->HandleHandshake(Username)) - { - // The client is not welcome here, they have been sent a Kick packet already - return; - } + if (!m_Client->HandleHandshake(Username)) + { + // The client is not welcome here, they have been sent a Kick packet already + return; + } - cServer * Server = cRoot::Get()->GetServer(); - // If auth is required, then send the encryption request: - if (Server->ShouldAuthenticate()) - { - cPacketizer Pkt(*this, 0x01); - Pkt.WriteString(Server->GetServerID()); - const AString & PubKeyDer = Server->GetPublicKeyDER(); - Pkt.WriteVarInt32(static_cast<UInt32>(PubKeyDer.size())); - Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size()); - Pkt.WriteVarInt32(4); - Pkt.WriteBEInt32(static_cast<int>(reinterpret_cast<intptr_t>(this))); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) - m_Client->SetUsername(Username); - return; - } + cServer * Server = cRoot::Get()->GetServer(); + // If auth is required, then send the encryption request: + if (Server->ShouldAuthenticate()) + { + cPacketizer Pkt(*this, 0x01); + Pkt.WriteString(Server->GetServerID()); + const AString & PubKeyDer = Server->GetPublicKeyDER(); + Pkt.WriteVarInt32(static_cast<UInt32>(PubKeyDer.size())); + Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size()); + Pkt.WriteVarInt32(4); + Pkt.WriteBEInt32(static_cast<int>(reinterpret_cast<intptr_t>(this))); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) + m_Client->SetUsername(Username); + return; + } - m_Client->HandleLogin(Username); + m_Client->HandleLogin(Username); } @@ -2281,7 +2281,7 @@ void cProtocol_1_8_0::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketAnimation(cByteBuffer & a_ByteBuffer) { - m_Client->HandleAnimation(0); // Packet exists solely for arm-swing notification + m_Client->HandleAnimation(0); // Packet exists solely for arm-swing notification } @@ -2290,16 +2290,16 @@ void cProtocol_1_8_0::HandlePacketAnimation(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status); - int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) - { - return; - } + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + { + return; + } - HANDLE_READ(a_ByteBuffer, ReadBEInt8, Int8, Face); - m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), Status); + HANDLE_READ(a_ByteBuffer, ReadBEInt8, Int8, Face); + m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), Status); } @@ -2308,21 +2308,21 @@ void cProtocol_1_8_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) { - int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) - { - return; - } + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + { + return; + } - HANDLE_READ(a_ByteBuffer, ReadBEInt8, Int8, Face); + HANDLE_READ(a_ByteBuffer, ReadBEInt8, Int8, Face); - cItem Item; - ReadItem(a_ByteBuffer, Item, 3); + cItem Item; + ReadItem(a_ByteBuffer, Item, 3); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorX); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorY); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorZ); - m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorX); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorY); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorZ); + m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); } @@ -2331,8 +2331,8 @@ void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message); - m_Client->HandleChat(Message); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message); + m_Client->HandleChat(Message); } @@ -2341,16 +2341,16 @@ void cProtocol_1_8_0::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts); - m_Client->SetLocale(Locale); - m_Client->SetViewDistance(ViewDistance); - m_Client->GetPlayer()->SetSkinParts(SkinParts); - // TODO: Handle chat flags and chat colors + m_Client->SetLocale(Locale); + m_Client->SetViewDistance(ViewDistance); + m_Client->GetPlayer()->SetSkinParts(SkinParts); + // TODO: Handle chat flags and chat colors } @@ -2359,30 +2359,30 @@ void cProtocol_1_8_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ActionID); - switch (ActionID) - { - case 0: - { - // Respawn - m_Client->HandleRespawn(); - break; - } - case 1: - { - // Request stats - const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); - SendStatistics(Manager); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ActionID); + switch (ActionID) + { + case 0: + { + // Respawn + m_Client->HandleRespawn(); + break; + } + case 1: + { + // Request stats + const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); + SendStatistics(Manager); - break; - } - case 2: - { - // Open Inventory achievement - m_Client->GetPlayer()->AwardAchievement(achOpenInv); - break; - } - } + break; + } + case 2: + { + // Open Inventory achievement + m_Client->GetPlayer()->AwardAchievement(achOpenInv); + break; + } + } } @@ -2391,13 +2391,13 @@ void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); - cItem Item; - if (!ReadItem(a_ByteBuffer, Item)) - { - return; - } - m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == -1) ? caLeftClickOutside : caLeftClick); + HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); + cItem Item; + if (!ReadItem(a_ByteBuffer, Item)) + { + return; + } + m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == -1) ? caLeftClickOutside : caLeftClick); } @@ -2406,18 +2406,18 @@ void cProtocol_1_8_0::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBu void cProtocol_1_8_0::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost); - switch (Action) - { - case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch - case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch - case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed - case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting - case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting - } + switch (Action) + { + case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch + case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch + case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed + case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting + case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting + } } @@ -2426,8 +2426,8 @@ void cProtocol_1_8_0::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID); - m_Client->HandleKeepAlive(KeepAliveID); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID); + m_Client->HandleKeepAlive(KeepAliveID); } @@ -2436,8 +2436,8 @@ void cProtocol_1_8_0::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPlayer(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - // TODO: m_Client->HandlePlayerOnGround(IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + // TODO: m_Client->HandlePlayerOnGround(IsOnGround); } @@ -2446,22 +2446,22 @@ void cProtocol_1_8_0::HandlePacketPlayer(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Flags); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Flags); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); - // COnvert the bitfield into individual boolean flags: - bool IsFlying = false, CanFly = false; - if ((Flags & 2) != 0) - { - IsFlying = true; - } - if ((Flags & 4) != 0) - { - CanFly = true; - } + // COnvert the bitfield into individual boolean flags: + bool IsFlying = false, CanFly = false; + if ((Flags & 2) != 0) + { + IsFlying = true; + } + if ((Flags & 4) != 0) + { + CanFly = true; + } - m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed); + m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed); } @@ -2470,10 +2470,10 @@ void cProtocol_1_8_0::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround); } @@ -2482,11 +2482,11 @@ void cProtocol_1_8_0::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + (m_Client->GetPlayer()->IsCrouched() ? 1.54 : 1.62), IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + (m_Client->GetPlayer()->IsCrouched() ? 1.54 : 1.62), IsOnGround); } @@ -2495,13 +2495,13 @@ void cProtocol_1_8_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround); } @@ -2510,29 +2510,29 @@ void cProtocol_1_8_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - // If the plugin channel is recognized vanilla, handle it directly: - if (Channel.substr(0, 3) == "MC|") - { - HandleVanillaPluginMessage(a_ByteBuffer, Channel); + // If the plugin channel is recognized vanilla, handle it directly: + if (Channel.substr(0, 3) == "MC|") + { + HandleVanillaPluginMessage(a_ByteBuffer, Channel); - // Skip any unread data (vanilla sometimes sends garbage at the end of a packet; #1692): - if (a_ByteBuffer.GetReadableSpace() > 1) - { - LOGD("Protocol 1.8: Skipping garbage data at the end of a vanilla PluginMessage packet, %u bytes", - static_cast<unsigned>(a_ByteBuffer.GetReadableSpace() - 1) - ); - a_ByteBuffer.SkipRead(a_ByteBuffer.GetReadableSpace() - 1); - } + // Skip any unread data (vanilla sometimes sends garbage at the end of a packet; #1692): + if (a_ByteBuffer.GetReadableSpace() > 1) + { + LOGD("Protocol 1.8: Skipping garbage data at the end of a vanilla PluginMessage packet, %u bytes", + static_cast<unsigned>(a_ByteBuffer.GetReadableSpace() - 1) + ); + a_ByteBuffer.SkipRead(a_ByteBuffer.GetReadableSpace() - 1); + } - return; - } + return; + } - // Read the plugin message and relay to clienthandle: - AString Data; - VERIFY(a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)); // Always succeeds - m_Client->HandlePluginMessage(Channel, Data); + // Read the plugin message and relay to clienthandle: + AString Data; + VERIFY(a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)); // Always succeeds + m_Client->HandlePluginMessage(Channel, Data); } @@ -2541,8 +2541,8 @@ void cProtocol_1_8_0::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); - m_Client->HandleSlotSelected(SlotNum); + HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); + m_Client->HandleSlotSelected(SlotNum); } @@ -2551,13 +2551,13 @@ void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketSpectate(cByteBuffer &a_ByteBuffer) { - AString playerUUID; - if (!a_ByteBuffer.ReadUUID(playerUUID)) - { - return; - } + AString playerUUID; + if (!a_ByteBuffer.ReadUUID(playerUUID)) + { + return; + } - m_Client->HandleSpectate(playerUUID); + m_Client->HandleSpectate(playerUUID); } @@ -2566,22 +2566,22 @@ void cProtocol_1_8_0::HandlePacketSpectate(cByteBuffer &a_ByteBuffer) void cProtocol_1_8_0::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Flags); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Flags); - if ((Flags & 0x2) != 0) - { - m_Client->HandleUnmount(); - } - else if ((Flags & 0x1) != 0) - { - // jump - } - else - { - m_Client->HandleSteerVehicle(Forward, Sideways); - } + if ((Flags & 0x2) != 0) + { + m_Client->HandleUnmount(); + } + else if ((Flags & 0x1) != 0) + { + // jump + } + else + { + m_Client->HandleSteerVehicle(Forward, Sideways); + } } @@ -2590,15 +2590,15 @@ void cProtocol_1_8_0::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, HasPosition); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, HasPosition); - if (HasPosition) - { - HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Position); - } + if (HasPosition) + { + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Position); + } - m_Client->HandleTabCompletion(Text); + m_Client->HandleTabCompletion(Text); } @@ -2607,25 +2607,25 @@ void cProtocol_1_8_0::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) { - int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) - { - return; - } + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + { + return; + } - AString Lines[4]; - Json::Value root; - Json::Reader reader; - for (int i = 0; i < 4; i++) - { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line); - if (reader.parse(Line, root, false)) - { - Lines[i] = root.asString(); - } - } + AString Lines[4]; + Json::Value root; + Json::Reader reader; + for (int i = 0; i < 4; i++) + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line); + if (reader.parse(Line, root, false)) + { + Lines[i] = root.asString(); + } + } - m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Lines[0], Lines[1], Lines[2], Lines[3]); + m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Lines[0], Lines[1], Lines[2], Lines[3]); } @@ -2634,36 +2634,36 @@ void cProtocol_1_8_0::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type); - switch (Type) - { - case 0: - { - m_Client->HandleUseEntity(EntityID, false); - break; - } - case 1: - { - m_Client->HandleUseEntity(EntityID, true); - break; - } - case 2: - { - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ); + switch (Type) + { + case 0: + { + m_Client->HandleUseEntity(EntityID, false); + break; + } + case 1: + { + m_Client->HandleUseEntity(EntityID, true); + break; + } + case 2: + { + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ); - // TODO: Do anything - break; - } - default: - { - ASSERT(!"Unhandled use entity type!"); - return; - } - } + // TODO: Do anything + break; + } + default: + { + ASSERT(!"Unhandled use entity type!"); + return; + } + } } @@ -2672,10 +2672,10 @@ void cProtocol_1_8_0::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Enchantment); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Enchantment); - m_Client->HandleEnchantItem(WindowID, Enchantment); + m_Client->HandleEnchantItem(WindowID, Enchantment); } @@ -2684,53 +2684,53 @@ void cProtocol_1_8_0::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); - HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Button); - HANDLE_READ(a_ByteBuffer, ReadBEUInt16, UInt16, TransactionID); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode); - cItem Item; - ReadItem(a_ByteBuffer, Item); - - // Convert Button, Mode, SlotNum and HeldItem into eClickAction: - eClickAction Action; - switch ((Mode << 8) | Button) - { - case 0x0000: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caLeftClick : caLeftClickOutside; break; - case 0x0001: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caRightClick : caRightClickOutside; break; - case 0x0100: Action = caShiftLeftClick; break; - case 0x0101: Action = caShiftRightClick; break; - case 0x0200: Action = caNumber1; break; - case 0x0201: Action = caNumber2; break; - case 0x0202: Action = caNumber3; break; - case 0x0203: Action = caNumber4; break; - case 0x0204: Action = caNumber5; break; - case 0x0205: Action = caNumber6; break; - case 0x0206: Action = caNumber7; break; - case 0x0207: Action = caNumber8; break; - case 0x0208: Action = caNumber9; break; - case 0x0302: Action = caMiddleClick; break; - case 0x0400: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutsideHoldNothing : caDropKey; break; - case 0x0401: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break; - case 0x0500: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintBegin : caUnknown; break; - case 0x0501: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caLeftPaintProgress : caUnknown; break; - case 0x0502: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintEnd : caUnknown; break; - case 0x0504: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightPaintBegin : caUnknown; break; - case 0x0505: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caRightPaintProgress : caUnknown; break; - case 0x0506: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightPaintEnd : caUnknown; break; - case 0x0508: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caMiddlePaintBegin : caUnknown; break; - case 0x0509: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caMiddlePaintProgress : caUnknown; break; - case 0x050a: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caMiddlePaintEnd : caUnknown; break; - case 0x0600: Action = caDblClick; break; - default: - { - LOGWARNING("Unhandled window click mode / button combination: %d (0x%x)", (Mode << 8) | Button, (Mode << 8) | Button); - Action = caUnknown; - break; - } - } - - m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); + HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Button); + HANDLE_READ(a_ByteBuffer, ReadBEUInt16, UInt16, TransactionID); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode); + cItem Item; + ReadItem(a_ByteBuffer, Item); + + // Convert Button, Mode, SlotNum and HeldItem into eClickAction: + eClickAction Action; + switch ((Mode << 8) | Button) + { + case 0x0000: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caLeftClick : caLeftClickOutside; break; + case 0x0001: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caRightClick : caRightClickOutside; break; + case 0x0100: Action = caShiftLeftClick; break; + case 0x0101: Action = caShiftRightClick; break; + case 0x0200: Action = caNumber1; break; + case 0x0201: Action = caNumber2; break; + case 0x0202: Action = caNumber3; break; + case 0x0203: Action = caNumber4; break; + case 0x0204: Action = caNumber5; break; + case 0x0205: Action = caNumber6; break; + case 0x0206: Action = caNumber7; break; + case 0x0207: Action = caNumber8; break; + case 0x0208: Action = caNumber9; break; + case 0x0302: Action = caMiddleClick; break; + case 0x0400: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutsideHoldNothing : caDropKey; break; + case 0x0401: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break; + case 0x0500: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintBegin : caUnknown; break; + case 0x0501: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caLeftPaintProgress : caUnknown; break; + case 0x0502: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintEnd : caUnknown; break; + case 0x0504: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightPaintBegin : caUnknown; break; + case 0x0505: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caRightPaintProgress : caUnknown; break; + case 0x0506: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightPaintEnd : caUnknown; break; + case 0x0508: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caMiddlePaintBegin : caUnknown; break; + case 0x0509: Action = (SlotNum != SLOT_NUM_OUTSIDE) ? caMiddlePaintProgress : caUnknown; break; + case 0x050a: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caMiddlePaintEnd : caUnknown; break; + case 0x0600: Action = caDblClick; break; + default: + { + LOGWARNING("Unhandled window click mode / button combination: %d (0x%x)", (Mode << 8) | Button, (Mode << 8) | Button); + Action = caUnknown; + break; + } + } + + m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item); } @@ -2739,8 +2739,8 @@ void cProtocol_1_8_0::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); - m_Client->HandleWindowClose(WindowID); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID); + m_Client->HandleWindowClose(WindowID); } @@ -2749,63 +2749,63 @@ void cProtocol_1_8_0::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel) { - if (a_Channel == "MC|AdvCdm") - { - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode) - switch (Mode) - { - case 0x00: - { - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockX); - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockY); - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockZ); - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command); - m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command); - break; - } - - default: - { - m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %u (0x%02x)", Mode, Mode), mtFailure); - LOG("Unhandled MC|AdvCdm packet mode."); - return; - } - } // switch (Mode) - return; - } - else if (a_Channel == "MC|Brand") - { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand); - m_Client->SetClientBrand(Brand); - // Send back our brand, including the length: - SendPluginMessage("MC|Brand", "\x08""Cuberite"); - return; - } - else if (a_Channel == "MC|Beacon") - { - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, Effect1); - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, Effect2); - m_Client->HandleBeaconSelection(Effect1, Effect2); - return; - } - else if (a_Channel == "MC|ItemName") - { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, ItemName); - m_Client->HandleAnvilItemName(ItemName); - return; - } - else if (a_Channel == "MC|TrSel") - { - HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, SlotNum); - m_Client->HandleNPCTrade(SlotNum); - return; - } - LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); - - // Read the payload and send it through to the clienthandle: - AString Message; - VERIFY(a_ByteBuffer.ReadString(Message, a_ByteBuffer.GetReadableSpace() - 1)); - m_Client->HandlePluginMessage(a_Channel, Message); + if (a_Channel == "MC|AdvCdm") + { + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode) + switch (Mode) + { + case 0x00: + { + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockX); + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command); + m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command); + break; + } + + default: + { + m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %u (0x%02x)", Mode, Mode), mtFailure); + LOG("Unhandled MC|AdvCdm packet mode."); + return; + } + } // switch (Mode) + return; + } + else if (a_Channel == "MC|Brand") + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand); + m_Client->SetClientBrand(Brand); + // Send back our brand, including the length: + SendPluginMessage("MC|Brand", "\x08""Cuberite"); + return; + } + else if (a_Channel == "MC|Beacon") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, Effect1); + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, Effect2); + m_Client->HandleBeaconSelection(Effect1, Effect2); + return; + } + else if (a_Channel == "MC|ItemName") + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, ItemName); + m_Client->HandleAnvilItemName(ItemName); + return; + } + else if (a_Channel == "MC|TrSel") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, SlotNum); + m_Client->HandleNPCTrade(SlotNum); + return; + } + LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); + + // Read the payload and send it through to the clienthandle: + AString Message; + VERIFY(a_ByteBuffer.ReadString(Message, a_ByteBuffer.GetReadableSpace() - 1)); + m_Client->HandlePluginMessage(a_Channel, Message); } @@ -2814,22 +2814,22 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con void cProtocol_1_8_0::SendData(const char * a_Data, size_t a_Size) { - if (m_IsEncrypted) - { - Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) - while (a_Size > 0) - { - size_t NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size; - m_Encryptor.ProcessData(Encrypted, reinterpret_cast<Byte *>(const_cast<char*>(a_Data)), NumBytes); - m_Client->SendData(reinterpret_cast<const char *>(Encrypted), NumBytes); - a_Size -= NumBytes; - a_Data += NumBytes; - } - } - else - { - m_Client->SendData(a_Data, a_Size); - } + if (m_IsEncrypted) + { + Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) + while (a_Size > 0) + { + size_t NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size; + m_Encryptor.ProcessData(Encrypted, reinterpret_cast<Byte *>(const_cast<char*>(a_Data)), NumBytes); + m_Client->SendData(reinterpret_cast<const char *>(Encrypted), NumBytes); + a_Size -= NumBytes; + a_Data += NumBytes; + } + } + else + { + m_Client->SendData(a_Data, a_Size); + } } @@ -2838,33 +2838,33 @@ void cProtocol_1_8_0::SendData(const char * a_Data, size_t a_Size) bool cProtocol_1_8_0::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) { - HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemType); - if (ItemType == -1) - { - // The item is empty, no more data follows - a_Item.Empty(); - return true; - } - a_Item.m_ItemType = ItemType; + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemType); + if (ItemType == -1) + { + // The item is empty, no more data follows + a_Item.Empty(); + return true; + } + a_Item.m_ItemType = ItemType; - HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount); - HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage); - a_Item.m_ItemCount = ItemCount; - a_Item.m_ItemDamage = ItemDamage; - if (ItemCount <= 0) - { - a_Item.Empty(); - } + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount); + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage); + a_Item.m_ItemCount = ItemCount; + a_Item.m_ItemDamage = ItemDamage; + if (ItemCount <= 0) + { + a_Item.Empty(); + } - AString Metadata; - if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes - 1) || (Metadata.size() == 0) || (Metadata[0] == 0)) - { - // No metadata - return true; - } + AString Metadata; + if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes - 1) || (Metadata.size() == 0) || (Metadata[0] == 0)) + { + // No metadata + return true; + } - ParseItemMetadata(a_Item, Metadata); - return true; + ParseItemMetadata(a_Item, Metadata); + return true; } @@ -2873,71 +2873,71 @@ bool cProtocol_1_8_0::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_ void cProtocol_1_8_0::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { - // Parse into NBT: - cParsedNBT NBT(a_Metadata.data(), a_Metadata.size()); - if (!NBT.IsValid()) - { - AString HexDump; - CreateHexDump(HexDump, a_Metadata.data(), std::max<size_t>(a_Metadata.size(), 1024), 16); - LOGWARNING("Cannot parse NBT item metadata: %s at (" SIZE_T_FMT " / " SIZE_T_FMT " bytes)\n%s", - NBT.GetErrorCode().message().c_str(), NBT.GetErrorPos(), a_Metadata.size(), HexDump.c_str() - ); - return; - } - - // Load enchantments and custom display names from the NBT data: - for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) - { - AString TagName = NBT.GetName(tag); - switch (NBT.GetType(tag)) - { - case TAG_List: - { - if ((TagName == "ench") || (TagName == "StoredEnchantments")) // Enchantments tags - { - EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); - } - break; - } - case TAG_Compound: - { - if (TagName == "display") // Custom name and lore tag - { - for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) - { - if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag - { - a_Item.m_CustomName = NBT.GetString(displaytag); - } - else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag - { - for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings - { - a_Item.m_LoreTable.push_back(NBT.GetString(loretag)); - } - } - else if ((NBT.GetType(displaytag) == TAG_Int) && (NBT.GetName(displaytag) == "color")) - { - a_Item.m_ItemColor.m_Color = static_cast<unsigned int>(NBT.GetInt(displaytag)); - } - } - } - else if ((TagName == "Fireworks") || (TagName == "Explosion")) - { - cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, NBT, tag, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType)); - } - break; - } - case TAG_Int: - { - if (TagName == "RepairCost") - { - a_Item.m_RepairCost = NBT.GetInt(tag); - } - } - default: LOGD("Unimplemented NBT data when parsing!"); break; - } - } + // Parse into NBT: + cParsedNBT NBT(a_Metadata.data(), a_Metadata.size()); + if (!NBT.IsValid()) + { + AString HexDump; + CreateHexDump(HexDump, a_Metadata.data(), std::max<size_t>(a_Metadata.size(), 1024), 16); + LOGWARNING("Cannot parse NBT item metadata: %s at (" SIZE_T_FMT " / " SIZE_T_FMT " bytes)\n%s", + NBT.GetErrorCode().message().c_str(), NBT.GetErrorPos(), a_Metadata.size(), HexDump.c_str() + ); + return; + } + + // Load enchantments and custom display names from the NBT data: + for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) + { + AString TagName = NBT.GetName(tag); + switch (NBT.GetType(tag)) + { + case TAG_List: + { + if ((TagName == "ench") || (TagName == "StoredEnchantments")) // Enchantments tags + { + EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); + } + break; + } + case TAG_Compound: + { + if (TagName == "display") // Custom name and lore tag + { + for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) + { + if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + { + a_Item.m_CustomName = NBT.GetString(displaytag); + } + else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + { + for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + { + a_Item.m_LoreTable.push_back(NBT.GetString(loretag)); + } + } + else if ((NBT.GetType(displaytag) == TAG_Int) && (NBT.GetName(displaytag) == "color")) + { + a_Item.m_ItemColor.m_Color = static_cast<unsigned int>(NBT.GetInt(displaytag)); + } + } + } + else if ((TagName == "Fireworks") || (TagName == "Explosion")) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, NBT, tag, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType)); + } + break; + } + case TAG_Int: + { + if (TagName == "RepairCost") + { + a_Item.m_RepairCost = NBT.GetInt(tag); + } + } + default: LOGD("Unimplemented NBT data when parsing!"); break; + } + } } @@ -2946,20 +2946,20 @@ void cProtocol_1_8_0::ParseItemMetadata(cItem & a_Item, const AString & a_Metada void cProtocol_1_8_0::StartEncryption(const Byte * a_Key) { - m_Encryptor.Init(a_Key, a_Key); - m_Decryptor.Init(a_Key, a_Key); - m_IsEncrypted = true; + m_Encryptor.Init(a_Key, a_Key); + m_Decryptor.Init(a_Key, a_Key); + m_IsEncrypted = true; - // Prepare the m_AuthServerID: - cSha1Checksum Checksum; - cServer * Server = cRoot::Get()->GetServer(); - const AString & ServerID = Server->GetServerID(); - Checksum.Update(reinterpret_cast<const Byte *>(ServerID.c_str()), ServerID.length()); - Checksum.Update(a_Key, 16); - Checksum.Update(reinterpret_cast<const Byte *>(Server->GetPublicKeyDER().data()), Server->GetPublicKeyDER().size()); - Byte Digest[20]; - Checksum.Finalize(Digest); - cSha1Checksum::DigestToJava(Digest, m_AuthServerID); + // Prepare the m_AuthServerID: + cSha1Checksum Checksum; + cServer * Server = cRoot::Get()->GetServer(); + const AString & ServerID = Server->GetServerID(); + Checksum.Update(reinterpret_cast<const Byte *>(ServerID.c_str()), ServerID.length()); + Checksum.Update(a_Key, 16); + Checksum.Update(reinterpret_cast<const Byte *>(Server->GetPublicKeyDER().data()), Server->GetPublicKeyDER().size()); + Byte Digest[20]; + Checksum.Finalize(Digest); + cSha1Checksum::DigestToJava(Digest, m_AuthServerID); } @@ -2968,18 +2968,18 @@ void cProtocol_1_8_0::StartEncryption(const Byte * a_Key) eBlockFace cProtocol_1_8_0::FaceIntToBlockFace(Int8 a_BlockFace) { - // Normalize the blockface values returned from the protocol - // Anything known gets mapped 1:1, everything else returns BLOCK_FACE_NONE - switch (a_BlockFace) - { - case BLOCK_FACE_XM: return BLOCK_FACE_XM; - case BLOCK_FACE_XP: return BLOCK_FACE_XP; - case BLOCK_FACE_YM: return BLOCK_FACE_YM; - case BLOCK_FACE_YP: return BLOCK_FACE_YP; - case BLOCK_FACE_ZM: return BLOCK_FACE_ZM; - case BLOCK_FACE_ZP: return BLOCK_FACE_ZP; - default: return BLOCK_FACE_NONE; - } + // Normalize the blockface values returned from the protocol + // Anything known gets mapped 1:1, everything else returns BLOCK_FACE_NONE + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_XM; + case BLOCK_FACE_XP: return BLOCK_FACE_XP; + case BLOCK_FACE_YM: return BLOCK_FACE_YM; + case BLOCK_FACE_YP: return BLOCK_FACE_YP; + case BLOCK_FACE_ZM: return BLOCK_FACE_ZM; + case BLOCK_FACE_ZP: return BLOCK_FACE_ZP; + default: return BLOCK_FACE_NONE; + } } @@ -2991,58 +2991,58 @@ eBlockFace cProtocol_1_8_0::FaceIntToBlockFace(Int8 a_BlockFace) void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt) { - UInt32 PacketLen = static_cast<UInt32>(m_OutPacketBuffer.GetUsedSpace()); - AString PacketData, CompressedPacket; - m_OutPacketBuffer.ReadAll(PacketData); - m_OutPacketBuffer.CommitRead(); - - if ((m_State == 3) && (PacketLen >= 256)) - { - // Compress the packet payload: - if (!cProtocol_1_8_0::CompressPacket(PacketData, CompressedPacket)) - { - return; - } - } - else if (m_State == 3) - { - // The packet is not compressed, indicate this in the packet header: - m_OutPacketLenBuffer.WriteVarInt32(PacketLen + 1); - m_OutPacketLenBuffer.WriteVarInt32(0); - AString LengthData; - m_OutPacketLenBuffer.ReadAll(LengthData); - SendData(LengthData.data(), LengthData.size()); - } - else - { - // Compression doesn't apply to this state, send raw data: - m_OutPacketLenBuffer.WriteVarInt32(PacketLen); - AString LengthData; - m_OutPacketLenBuffer.ReadAll(LengthData); - SendData(LengthData.data(), LengthData.size()); - } - - // Send the packet's payload, either direct or compressed: - if (CompressedPacket.empty()) - { - m_OutPacketLenBuffer.CommitRead(); - SendData(PacketData.data(), PacketData.size()); - } - else - { - SendData(CompressedPacket.data(), CompressedPacket.size()); - } - - // Log the comm into logfile: - if (g_ShouldLogCommOut && m_CommLogFile.IsOpen()) - { - AString Hex; - ASSERT(PacketData.size() > 0); - CreateHexDump(Hex, PacketData.data(), PacketData.size(), 16); - m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload (incl. type):\n%s\n", - a_Pkt.GetPacketType(), a_Pkt.GetPacketType(), PacketLen, PacketLen, m_State, Hex.c_str() - ); - } + UInt32 PacketLen = static_cast<UInt32>(m_OutPacketBuffer.GetUsedSpace()); + AString PacketData, CompressedPacket; + m_OutPacketBuffer.ReadAll(PacketData); + m_OutPacketBuffer.CommitRead(); + + if ((m_State == 3) && (PacketLen >= 256)) + { + // Compress the packet payload: + if (!cProtocol_1_8_0::CompressPacket(PacketData, CompressedPacket)) + { + return; + } + } + else if (m_State == 3) + { + // The packet is not compressed, indicate this in the packet header: + m_OutPacketLenBuffer.WriteVarInt32(PacketLen + 1); + m_OutPacketLenBuffer.WriteVarInt32(0); + AString LengthData; + m_OutPacketLenBuffer.ReadAll(LengthData); + SendData(LengthData.data(), LengthData.size()); + } + else + { + // Compression doesn't apply to this state, send raw data: + m_OutPacketLenBuffer.WriteVarInt32(PacketLen); + AString LengthData; + m_OutPacketLenBuffer.ReadAll(LengthData); + SendData(LengthData.data(), LengthData.size()); + } + + // Send the packet's payload, either direct or compressed: + if (CompressedPacket.empty()) + { + m_OutPacketLenBuffer.CommitRead(); + SendData(PacketData.data(), PacketData.size()); + } + else + { + SendData(CompressedPacket.data(), CompressedPacket.size()); + } + + // Log the comm into logfile: + if (g_ShouldLogCommOut && m_CommLogFile.IsOpen()) + { + AString Hex; + ASSERT(PacketData.size() > 0); + CreateHexDump(Hex, PacketData.data(), PacketData.size(), 16); + m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload (incl. type):\n%s\n", + a_Pkt.GetPacketType(), a_Pkt.GetPacketType(), PacketLen, PacketLen, m_State, Hex.c_str() + ); + } } @@ -3051,80 +3051,80 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt) void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) { - short ItemType = a_Item.m_ItemType; - ASSERT(ItemType >= -1); // Check validity of packets in debug runtime - if (ItemType <= 0) - { - // Fix, to make sure no invalid values are sent. - ItemType = -1; - } - - if (a_Item.IsEmpty()) - { - a_Pkt.WriteBEInt16(-1); - return; - } - - a_Pkt.WriteBEInt16(ItemType); - a_Pkt.WriteBEInt8(a_Item.m_ItemCount); - a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); - - if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid()) - { - a_Pkt.WriteBEInt8(0); - return; - } - - - // Send the enchantments and custom names: - cFastNBTWriter Writer; - if (a_Item.m_RepairCost != 0) - { - Writer.AddInt("RepairCost", a_Item.m_RepairCost); - } - if (!a_Item.m_Enchantments.IsEmpty()) - { - const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; - EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); - } - if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid()) - { - Writer.BeginCompound("display"); - if (a_Item.m_ItemColor.IsValid()) - { - Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color)); - } - - if (!a_Item.IsCustomNameEmpty()) - { - Writer.AddString("Name", a_Item.m_CustomName.c_str()); - } - if (!a_Item.IsLoreEmpty()) - { - Writer.BeginList("Lore", TAG_String); - - for (const auto & Line : a_Item.m_LoreTable) - { - Writer.AddString("", Line); - } - - Writer.EndList(); - } - Writer.EndCompound(); - } - if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) - { - cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType)); - } - Writer.Finish(); - - AString Result = Writer.GetResult(); - if (Result.size() == 0) - { - a_Pkt.WriteBEInt8(0); - return; - } - a_Pkt.WriteBuf(Result.data(), Result.size()); + short ItemType = a_Item.m_ItemType; + ASSERT(ItemType >= -1); // Check validity of packets in debug runtime + if (ItemType <= 0) + { + // Fix, to make sure no invalid values are sent. + ItemType = -1; + } + + if (a_Item.IsEmpty()) + { + a_Pkt.WriteBEInt16(-1); + return; + } + + a_Pkt.WriteBEInt16(ItemType); + a_Pkt.WriteBEInt8(a_Item.m_ItemCount); + a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); + + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid()) + { + a_Pkt.WriteBEInt8(0); + return; + } + + + // Send the enchantments and custom names: + cFastNBTWriter Writer; + if (a_Item.m_RepairCost != 0) + { + Writer.AddInt("RepairCost", a_Item.m_RepairCost); + } + if (!a_Item.m_Enchantments.IsEmpty()) + { + const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; + EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); + } + if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid()) + { + Writer.BeginCompound("display"); + if (a_Item.m_ItemColor.IsValid()) + { + Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color)); + } + + if (!a_Item.IsCustomNameEmpty()) + { + Writer.AddString("Name", a_Item.m_CustomName.c_str()); + } + if (!a_Item.IsLoreEmpty()) + { + Writer.BeginList("Lore", TAG_String); + + for (const auto & Line : a_Item.m_LoreTable) + { + Writer.AddString("", Line); + } + + Writer.EndList(); + } + Writer.EndCompound(); + } + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType)); + } + Writer.Finish(); + + AString Result = Writer.GetResult(); + if (Result.size() == 0) + { + a_Pkt.WriteBEInt8(0); + return; + } + a_Pkt.WriteBuf(Result.data(), Result.size()); } @@ -3133,102 +3133,102 @@ void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) { - cFastNBTWriter Writer; - - switch (a_BlockEntity.GetBlockType()) - { - case E_BLOCK_BEACON: - { - auto & BeaconEntity = reinterpret_cast<const cBeaconEntity &>(a_BlockEntity); - Writer.AddInt("x", BeaconEntity.GetPosX()); - Writer.AddInt("y", BeaconEntity.GetPosY()); - Writer.AddInt("z", BeaconEntity.GetPosZ()); - Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); - Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); - Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); - Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - break; - } - - case E_BLOCK_COMMAND_BLOCK: - { - auto & CommandBlockEntity = reinterpret_cast<const cCommandBlockEntity &>(a_BlockEntity); - Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this - Writer.AddInt("SuccessCount", CommandBlockEntity.GetResult()); - Writer.AddInt("x", CommandBlockEntity.GetPosX()); - Writer.AddInt("y", CommandBlockEntity.GetPosY()); - Writer.AddInt("z", CommandBlockEntity.GetPosZ()); - Writer.AddString("Command", CommandBlockEntity.GetCommand().c_str()); - // You can set custom names for windows in Vanilla - // For a command block, this would be the 'name' prepended to anything it outputs into global chat - // MCS doesn't have this, so just leave it @ '@'. (geddit?) - Writer.AddString("CustomName", "@"); - Writer.AddString("id", "Control"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - if (!CommandBlockEntity.GetLastOutput().empty()) - { - Writer.AddString("LastOutput", Printf("{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str())); - } - break; - } - - case E_BLOCK_HEAD: - { - auto & MobHeadEntity = reinterpret_cast<const cMobHeadEntity &>(a_BlockEntity); - Writer.AddInt("x", MobHeadEntity.GetPosX()); - Writer.AddInt("y", MobHeadEntity.GetPosY()); - Writer.AddInt("z", MobHeadEntity.GetPosZ()); - Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF); - Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF); - Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - - // The new Block Entity format for a Mob Head. See: http://minecraft.gamepedia.com/Head#Block_entity - Writer.BeginCompound("Owner"); - Writer.AddString("Id", MobHeadEntity.GetOwnerUUID()); - Writer.AddString("Name", MobHeadEntity.GetOwnerName()); - Writer.BeginCompound("Properties"); - Writer.BeginList("textures", TAG_Compound); - Writer.BeginCompound(""); - Writer.AddString("Signature", MobHeadEntity.GetOwnerTextureSignature()); - Writer.AddString("Value", MobHeadEntity.GetOwnerTexture()); - Writer.EndCompound(); - Writer.EndList(); - Writer.EndCompound(); - Writer.EndCompound(); - break; - } - - case E_BLOCK_FLOWER_POT: - { - auto & FlowerPotEntity = reinterpret_cast<const cFlowerPotEntity &>(a_BlockEntity); - Writer.AddInt("x", FlowerPotEntity.GetPosX()); - Writer.AddInt("y", FlowerPotEntity.GetPosY()); - Writer.AddInt("z", FlowerPotEntity.GetPosZ()); - Writer.AddInt("Item", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemType)); - Writer.AddInt("Data", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemDamage)); - Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - break; - } - - case E_BLOCK_MOB_SPAWNER: - { - auto & MobSpawnerEntity = reinterpret_cast<const cMobSpawnerEntity &>(a_BlockEntity); - Writer.AddInt("x", MobSpawnerEntity.GetPosX()); - Writer.AddInt("y", MobSpawnerEntity.GetPosY()); - Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); - Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); - Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); - Writer.AddString("id", "MobSpawner"); - break; - } - - default: - { - break; - } - } - - Writer.Finish(); - a_Pkt.WriteBuf(Writer.GetResult().data(), Writer.GetResult().size()); + cFastNBTWriter Writer; + + switch (a_BlockEntity.GetBlockType()) + { + case E_BLOCK_BEACON: + { + auto & BeaconEntity = reinterpret_cast<const cBeaconEntity &>(a_BlockEntity); + Writer.AddInt("x", BeaconEntity.GetPosX()); + Writer.AddInt("y", BeaconEntity.GetPosY()); + Writer.AddInt("z", BeaconEntity.GetPosZ()); + Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); + Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); + Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); + Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + break; + } + + case E_BLOCK_COMMAND_BLOCK: + { + auto & CommandBlockEntity = reinterpret_cast<const cCommandBlockEntity &>(a_BlockEntity); + Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this + Writer.AddInt("SuccessCount", CommandBlockEntity.GetResult()); + Writer.AddInt("x", CommandBlockEntity.GetPosX()); + Writer.AddInt("y", CommandBlockEntity.GetPosY()); + Writer.AddInt("z", CommandBlockEntity.GetPosZ()); + Writer.AddString("Command", CommandBlockEntity.GetCommand().c_str()); + // You can set custom names for windows in Vanilla + // For a command block, this would be the 'name' prepended to anything it outputs into global chat + // MCS doesn't have this, so just leave it @ '@'. (geddit?) + Writer.AddString("CustomName", "@"); + Writer.AddString("id", "Control"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + if (!CommandBlockEntity.GetLastOutput().empty()) + { + Writer.AddString("LastOutput", Printf("{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str())); + } + break; + } + + case E_BLOCK_HEAD: + { + auto & MobHeadEntity = reinterpret_cast<const cMobHeadEntity &>(a_BlockEntity); + Writer.AddInt("x", MobHeadEntity.GetPosX()); + Writer.AddInt("y", MobHeadEntity.GetPosY()); + Writer.AddInt("z", MobHeadEntity.GetPosZ()); + Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF); + Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF); + Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + + // The new Block Entity format for a Mob Head. See: http://minecraft.gamepedia.com/Head#Block_entity + Writer.BeginCompound("Owner"); + Writer.AddString("Id", MobHeadEntity.GetOwnerUUID()); + Writer.AddString("Name", MobHeadEntity.GetOwnerName()); + Writer.BeginCompound("Properties"); + Writer.BeginList("textures", TAG_Compound); + Writer.BeginCompound(""); + Writer.AddString("Signature", MobHeadEntity.GetOwnerTextureSignature()); + Writer.AddString("Value", MobHeadEntity.GetOwnerTexture()); + Writer.EndCompound(); + Writer.EndList(); + Writer.EndCompound(); + Writer.EndCompound(); + break; + } + + case E_BLOCK_FLOWER_POT: + { + auto & FlowerPotEntity = reinterpret_cast<const cFlowerPotEntity &>(a_BlockEntity); + Writer.AddInt("x", FlowerPotEntity.GetPosX()); + Writer.AddInt("y", FlowerPotEntity.GetPosY()); + Writer.AddInt("z", FlowerPotEntity.GetPosZ()); + Writer.AddInt("Item", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemType)); + Writer.AddInt("Data", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemDamage)); + Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + break; + } + + case E_BLOCK_MOB_SPAWNER: + { + auto & MobSpawnerEntity = reinterpret_cast<const cMobSpawnerEntity &>(a_BlockEntity); + Writer.AddInt("x", MobSpawnerEntity.GetPosX()); + Writer.AddInt("y", MobSpawnerEntity.GetPosY()); + Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); + Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); + Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); + Writer.AddString("id", "MobSpawner"); + break; + } + + default: + { + break; + } + } + + Writer.Finish(); + a_Pkt.WriteBuf(Writer.GetResult().data(), Writer.GetResult().size()); } @@ -3237,141 +3237,141 @@ void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) { - // Common metadata: - Byte Flags = 0; - if (a_Entity.IsOnFire()) - { - Flags |= 0x01; - } - if (a_Entity.IsCrouched()) - { - Flags |= 0x02; - } - if (a_Entity.IsSprinting()) - { - Flags |= 0x08; - } - if (a_Entity.IsRclking()) - { - Flags |= 0x10; - } - if (a_Entity.IsInvisible()) - { - Flags |= 0x20; - } - a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0 - a_Pkt.WriteBEUInt8(Flags); - - switch (a_Entity.GetEntityType()) - { - case cEntity::etPlayer: - { - auto & Player = reinterpret_cast<const cPlayer &>(a_Entity); - - // Player health (not handled since players aren't monsters) - a_Pkt.WriteBEUInt8(0x66); - a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth())); - - // Skin flags - a_Pkt.WriteBEUInt8(0x0A); - a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts())); - - break; - } - case cEntity::etPickup: - { - a_Pkt.WriteBEUInt8((5 << 5) | 10); // Slot(5) + index 10 - WriteItem(a_Pkt, reinterpret_cast<const cPickup &>(a_Entity).GetItem()); - break; - } - case cEntity::etMinecart: - { - a_Pkt.WriteBEUInt8(0x51); - - // The following expression makes Minecarts shake more with less health or higher damage taken - // It gets half the maximum health, and takes it away from the current health minus the half health: - /* - Health: 5 | 3 - (5 - 3) = 1 (shake power) - Health: 3 | 3 - (3 - 3) = 3 - Health: 1 | 3 - (1 - 3) = 5 - */ - auto & Minecart = reinterpret_cast<const cMinecart &>(a_Entity); - a_Pkt.WriteBEInt32((((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * Minecart.LastDamage()) * 4); - a_Pkt.WriteBEUInt8(0x52); - a_Pkt.WriteBEInt32(1); // Shaking direction, doesn't seem to affect anything - a_Pkt.WriteBEUInt8(0x73); - a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10)); // Damage taken / shake effect multiplyer - - if (Minecart.GetPayload() == cMinecart::mpNone) - { - auto & RideableMinecart = reinterpret_cast<const cRideableMinecart &>(Minecart); - const cItem & MinecartContent = RideableMinecart.GetContent(); - if (!MinecartContent.IsEmpty()) - { - a_Pkt.WriteBEUInt8(0x54); - int Content = MinecartContent.m_ItemType; - Content |= MinecartContent.m_ItemDamage << 8; - a_Pkt.WriteBEInt32(Content); - a_Pkt.WriteBEUInt8(0x55); - a_Pkt.WriteBEInt32(RideableMinecart.GetBlockHeight()); - a_Pkt.WriteBEUInt8(0x56); - a_Pkt.WriteBEUInt8(1); - } - } - else if (Minecart.GetPayload() == cMinecart::mpFurnace) - { - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(reinterpret_cast<const cMinecartWithFurnace &>(Minecart).IsFueled() ? 1 : 0); - } - break; - } // case etMinecart - - case cEntity::etProjectile: - { - auto & Projectile = reinterpret_cast<const cProjectileEntity &>(a_Entity); - switch (Projectile.GetProjectileKind()) - { - case cProjectileEntity::pkArrow: - { - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(reinterpret_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0); - break; - } - case cProjectileEntity::pkFirework: - { - a_Pkt.WriteBEUInt8(0xa8); - WriteItem(a_Pkt, reinterpret_cast<const cFireworkEntity &>(Projectile).GetItem()); - break; - } - default: - { - break; - } - } - break; - } // case etProjectile - - case cEntity::etMonster: - { - WriteMobMetadata(a_Pkt, reinterpret_cast<const cMonster &>(a_Entity)); - break; - } - - case cEntity::etItemFrame: - { - auto & Frame = reinterpret_cast<const cItemFrame &>(a_Entity); - a_Pkt.WriteBEUInt8(0xa8); - WriteItem(a_Pkt, Frame.GetItem()); - a_Pkt.WriteBEUInt8(0x09); - a_Pkt.WriteBEUInt8(Frame.GetItemRotation()); - break; - } // case etItemFrame - - default: - { - break; - } - } + // Common metadata: + Byte Flags = 0; + if (a_Entity.IsOnFire()) + { + Flags |= 0x01; + } + if (a_Entity.IsCrouched()) + { + Flags |= 0x02; + } + if (a_Entity.IsSprinting()) + { + Flags |= 0x08; + } + if (a_Entity.IsRclking()) + { + Flags |= 0x10; + } + if (a_Entity.IsInvisible()) + { + Flags |= 0x20; + } + a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0 + a_Pkt.WriteBEUInt8(Flags); + + switch (a_Entity.GetEntityType()) + { + case cEntity::etPlayer: + { + auto & Player = reinterpret_cast<const cPlayer &>(a_Entity); + + // Player health (not handled since players aren't monsters) + a_Pkt.WriteBEUInt8(0x66); + a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth())); + + // Skin flags + a_Pkt.WriteBEUInt8(0x0A); + a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts())); + + break; + } + case cEntity::etPickup: + { + a_Pkt.WriteBEUInt8((5 << 5) | 10); // Slot(5) + index 10 + WriteItem(a_Pkt, reinterpret_cast<const cPickup &>(a_Entity).GetItem()); + break; + } + case cEntity::etMinecart: + { + a_Pkt.WriteBEUInt8(0x51); + + // The following expression makes Minecarts shake more with less health or higher damage taken + // It gets half the maximum health, and takes it away from the current health minus the half health: + /* + Health: 5 | 3 - (5 - 3) = 1 (shake power) + Health: 3 | 3 - (3 - 3) = 3 + Health: 1 | 3 - (1 - 3) = 5 + */ + auto & Minecart = reinterpret_cast<const cMinecart &>(a_Entity); + a_Pkt.WriteBEInt32((((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * Minecart.LastDamage()) * 4); + a_Pkt.WriteBEUInt8(0x52); + a_Pkt.WriteBEInt32(1); // Shaking direction, doesn't seem to affect anything + a_Pkt.WriteBEUInt8(0x73); + a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10)); // Damage taken / shake effect multiplyer + + if (Minecart.GetPayload() == cMinecart::mpNone) + { + auto & RideableMinecart = reinterpret_cast<const cRideableMinecart &>(Minecart); + const cItem & MinecartContent = RideableMinecart.GetContent(); + if (!MinecartContent.IsEmpty()) + { + a_Pkt.WriteBEUInt8(0x54); + int Content = MinecartContent.m_ItemType; + Content |= MinecartContent.m_ItemDamage << 8; + a_Pkt.WriteBEInt32(Content); + a_Pkt.WriteBEUInt8(0x55); + a_Pkt.WriteBEInt32(RideableMinecart.GetBlockHeight()); + a_Pkt.WriteBEUInt8(0x56); + a_Pkt.WriteBEUInt8(1); + } + } + else if (Minecart.GetPayload() == cMinecart::mpFurnace) + { + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(reinterpret_cast<const cMinecartWithFurnace &>(Minecart).IsFueled() ? 1 : 0); + } + break; + } // case etMinecart + + case cEntity::etProjectile: + { + auto & Projectile = reinterpret_cast<const cProjectileEntity &>(a_Entity); + switch (Projectile.GetProjectileKind()) + { + case cProjectileEntity::pkArrow: + { + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(reinterpret_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0); + break; + } + case cProjectileEntity::pkFirework: + { + a_Pkt.WriteBEUInt8(0xa8); + WriteItem(a_Pkt, reinterpret_cast<const cFireworkEntity &>(Projectile).GetItem()); + break; + } + default: + { + break; + } + } + break; + } // case etProjectile + + case cEntity::etMonster: + { + WriteMobMetadata(a_Pkt, reinterpret_cast<const cMonster &>(a_Entity)); + break; + } + + case cEntity::etItemFrame: + { + auto & Frame = reinterpret_cast<const cItemFrame &>(a_Entity); + a_Pkt.WriteBEUInt8(0xa8); + WriteItem(a_Pkt, Frame.GetItem()); + a_Pkt.WriteBEUInt8(0x09); + a_Pkt.WriteBEUInt8(Frame.GetItemRotation()); + break; + } // case etItemFrame + + default: + { + break; + } + } } @@ -3380,266 +3380,266 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) { - // Living Enitiy Metadata - if (a_Mob.HasCustomName()) - { - a_Pkt.WriteBEUInt8(0x82); - a_Pkt.WriteString(a_Mob.GetCustomName()); - - a_Pkt.WriteBEUInt8(0x03); - a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible()); - } - - a_Pkt.WriteBEUInt8(0x66); - a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); - - switch (a_Mob.GetMobType()) - { - case mtBat: - { - auto & Bat = reinterpret_cast<const cBat &>(a_Mob); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(Bat.IsHanging() ? 1 : 0); - break; - } // case mtBat - - case mtCreeper: - { - auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(Creeper.IsBlowing() ? 1 : 255); - a_Pkt.WriteBEUInt8(0x11); - a_Pkt.WriteBEUInt8(Creeper.IsCharged() ? 1 : 0); - break; - } // case mtCreeper - - case mtEnderman: - { - auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob); - a_Pkt.WriteBEUInt8(0x30); - a_Pkt.WriteBEInt16(static_cast<Byte>(Enderman.GetCarriedBlock())); - a_Pkt.WriteBEUInt8(0x11); - a_Pkt.WriteBEUInt8(static_cast<Byte>(Enderman.GetCarriedMeta())); - a_Pkt.WriteBEUInt8(0x12); - a_Pkt.WriteBEUInt8(Enderman.IsScreaming() ? 1 : 0); - break; - } // case mtEnderman - - case mtGhast: - { - auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(Ghast.IsCharging()); - break; - } // case mtGhast - - case mtHorse: - { - auto & Horse = reinterpret_cast<const cHorse &>(a_Mob); - int Flags = 0; - if (Horse.IsTame()) - { - Flags |= 0x02; - } - if (Horse.IsSaddled()) - { - Flags |= 0x04; - } - if (Horse.IsChested()) - { - Flags |= 0x08; - } - if (Horse.IsEating()) - { - Flags |= 0x20; - } - if (Horse.IsRearing()) - { - Flags |= 0x40; - } - if (Horse.IsMthOpen()) - { - Flags |= 0x80; - } - a_Pkt.WriteBEUInt8(0x50); // Int at index 16 - a_Pkt.WriteBEInt32(Flags); - a_Pkt.WriteBEUInt8(0x13); // Byte at index 19 - a_Pkt.WriteBEUInt8(static_cast<UInt8>(Horse.GetHorseType())); - a_Pkt.WriteBEUInt8(0x54); // Int at index 20 - int Appearance = 0; - Appearance = Horse.GetHorseColor(); - Appearance |= Horse.GetHorseStyle() << 8; - a_Pkt.WriteBEInt32(Appearance); - a_Pkt.WriteBEUInt8(0x56); // Int at index 22 - a_Pkt.WriteBEInt32(Horse.GetHorseArmour()); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Horse.IsBaby() ? -1 : (Horse.IsInLoveCooldown() ? 1 : 0)); - break; - } // case mtHorse - - case mtMagmaCube: - { - auto & MagmaCube = reinterpret_cast<const cMagmaCube &>(a_Mob); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(static_cast<UInt8>(MagmaCube.GetSize())); - break; - } // case mtMagmaCube - - case mtOcelot: - { - auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Ocelot.IsBaby() ? -1 : (Ocelot.IsInLoveCooldown() ? 1 : 0)); - break; - } // case mtOcelot - - case mtCow: - { - auto & Cow = reinterpret_cast<const cCow &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Cow.IsBaby() ? -1 : (Cow.IsInLoveCooldown() ? 1 : 0)); - break; - } // case mtCow - - case mtChicken: - { - auto & Chicken = reinterpret_cast<const cChicken &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Chicken.IsBaby() ? -1 : (Chicken.IsInLoveCooldown() ? 1 : 0)); - break; - } // case mtChicken - - case mtPig: - { - auto & Pig = reinterpret_cast<const cPig &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Pig.IsBaby() ? -1 : (Pig.IsInLoveCooldown() ? 1 : 0)); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(Pig.IsSaddled() ? 1 : 0); - break; - } // case mtPig - - case mtSheep: - { - auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Sheep.IsBaby() ? -1 : (Sheep.IsInLoveCooldown() ? 1 : 0)); - - a_Pkt.WriteBEUInt8(0x10); - Byte SheepMetadata = 0; - SheepMetadata = static_cast<Byte>(Sheep.GetFurColor()); - if (Sheep.IsSheared()) - { - SheepMetadata |= 0x10; - } - a_Pkt.WriteBEUInt8(SheepMetadata); - break; - } // case mtSheep - - case mtRabbit: - { - auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob); - a_Pkt.WriteBEUInt8(0x12); - a_Pkt.WriteBEUInt8(static_cast<UInt8>(Rabbit.GetRabbitType())); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Rabbit.IsBaby() ? -1 : (Rabbit.IsInLoveCooldown() ? 1 : 0)); - break; - } // case mtRabbit - - case mtSkeleton: - { - auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0d); - a_Pkt.WriteBEUInt8(Skeleton.IsWither() ? 1 : 0); - break; - } // case mtSkeleton - - case mtSlime: - { - auto & Slime = reinterpret_cast<const cSlime &>(a_Mob); - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(static_cast<UInt8>(Slime.GetSize())); - break; - } // case mtSlime - - case mtVillager: - { - auto & Villager = reinterpret_cast<const cVillager &>(a_Mob); - a_Pkt.WriteBEUInt8(0x50); - a_Pkt.WriteBEInt32(Villager.GetVilType()); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Villager.IsBaby() ? -1 : 0); - break; - } // case mtVillager - - case mtWitch: - { - auto & Witch = reinterpret_cast<const cWitch &>(a_Mob); - a_Pkt.WriteBEUInt8(0x15); - a_Pkt.WriteBEUInt8(Witch.IsAngry() ? 1 : 0); - break; - } // case mtWitch - - case mtWither: - { - auto & Wither = reinterpret_cast<const cWither &>(a_Mob); - a_Pkt.WriteBEUInt8(0x54); // Int at index 20 - a_Pkt.WriteBEInt32(static_cast<Int32>(Wither.GetWitherInvulnerableTicks())); - a_Pkt.WriteBEUInt8(0x66); // Float at index 6 - a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); - break; - } // case mtWither - - case mtWolf: - { - auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob); - Byte WolfStatus = 0; - if (Wolf.IsSitting()) - { - WolfStatus |= 0x1; - } - if (Wolf.IsAngry()) - { - WolfStatus |= 0x2; - } - if (Wolf.IsTame()) - { - WolfStatus |= 0x4; - } - a_Pkt.WriteBEUInt8(0x10); - a_Pkt.WriteBEUInt8(WolfStatus); - - a_Pkt.WriteBEUInt8(0x72); - a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); - a_Pkt.WriteBEUInt8(0x13); - a_Pkt.WriteBEUInt8(Wolf.IsBegging() ? 1 : 0); - a_Pkt.WriteBEUInt8(0x14); - a_Pkt.WriteBEUInt8(static_cast<UInt8>(Wolf.GetCollarColor())); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Wolf.IsBaby() ? -1 : 0); - break; - } // case mtWolf - - case mtZombie: - { - auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(Zombie.IsBaby() ? 1 : -1); - a_Pkt.WriteBEUInt8(0x0d); - a_Pkt.WriteBEUInt8(Zombie.IsVillagerZombie() ? 1 : 0); - a_Pkt.WriteBEUInt8(0x0e); - a_Pkt.WriteBEUInt8(Zombie.IsConverting() ? 1 : 0); - break; - } // case mtZombie - - case mtZombiePigman: - { - auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob); - a_Pkt.WriteBEUInt8(0x0c); - a_Pkt.WriteBEInt8(ZombiePigman.IsBaby() ? 1 : -1); - break; - } // case mtZombiePigman - } // switch (a_Mob.GetType()) + // Living Enitiy Metadata + if (a_Mob.HasCustomName()) + { + a_Pkt.WriteBEUInt8(0x82); + a_Pkt.WriteString(a_Mob.GetCustomName()); + + a_Pkt.WriteBEUInt8(0x03); + a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible()); + } + + a_Pkt.WriteBEUInt8(0x66); + a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); + + switch (a_Mob.GetMobType()) + { + case mtBat: + { + auto & Bat = reinterpret_cast<const cBat &>(a_Mob); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(Bat.IsHanging() ? 1 : 0); + break; + } // case mtBat + + case mtCreeper: + { + auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(Creeper.IsBlowing() ? 1 : 255); + a_Pkt.WriteBEUInt8(0x11); + a_Pkt.WriteBEUInt8(Creeper.IsCharged() ? 1 : 0); + break; + } // case mtCreeper + + case mtEnderman: + { + auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob); + a_Pkt.WriteBEUInt8(0x30); + a_Pkt.WriteBEInt16(static_cast<Byte>(Enderman.GetCarriedBlock())); + a_Pkt.WriteBEUInt8(0x11); + a_Pkt.WriteBEUInt8(static_cast<Byte>(Enderman.GetCarriedMeta())); + a_Pkt.WriteBEUInt8(0x12); + a_Pkt.WriteBEUInt8(Enderman.IsScreaming() ? 1 : 0); + break; + } // case mtEnderman + + case mtGhast: + { + auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(Ghast.IsCharging()); + break; + } // case mtGhast + + case mtHorse: + { + auto & Horse = reinterpret_cast<const cHorse &>(a_Mob); + int Flags = 0; + if (Horse.IsTame()) + { + Flags |= 0x02; + } + if (Horse.IsSaddled()) + { + Flags |= 0x04; + } + if (Horse.IsChested()) + { + Flags |= 0x08; + } + if (Horse.IsEating()) + { + Flags |= 0x20; + } + if (Horse.IsRearing()) + { + Flags |= 0x40; + } + if (Horse.IsMthOpen()) + { + Flags |= 0x80; + } + a_Pkt.WriteBEUInt8(0x50); // Int at index 16 + a_Pkt.WriteBEInt32(Flags); + a_Pkt.WriteBEUInt8(0x13); // Byte at index 19 + a_Pkt.WriteBEUInt8(static_cast<UInt8>(Horse.GetHorseType())); + a_Pkt.WriteBEUInt8(0x54); // Int at index 20 + int Appearance = 0; + Appearance = Horse.GetHorseColor(); + Appearance |= Horse.GetHorseStyle() << 8; + a_Pkt.WriteBEInt32(Appearance); + a_Pkt.WriteBEUInt8(0x56); // Int at index 22 + a_Pkt.WriteBEInt32(Horse.GetHorseArmour()); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Horse.IsBaby() ? -1 : (Horse.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + break; + } // case mtHorse + + case mtMagmaCube: + { + auto & MagmaCube = reinterpret_cast<const cMagmaCube &>(a_Mob); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(static_cast<UInt8>(MagmaCube.GetSize())); + break; + } // case mtMagmaCube + + case mtOcelot: + { + auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Ocelot.IsBaby() ? -1 : (Ocelot.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + break; + } // case mtOcelot + + case mtCow: + { + auto & Cow = reinterpret_cast<const cCow &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Cow.IsBaby() ? -1 : (Cow.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + break; + } // case mtCow + + case mtChicken: + { + auto & Chicken = reinterpret_cast<const cChicken &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Chicken.IsBaby() ? -1 : (Chicken.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + break; + } // case mtChicken + + case mtPig: + { + auto & Pig = reinterpret_cast<const cPig &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Pig.IsBaby() ? -1 : (Pig.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(Pig.IsSaddled() ? 1 : 0); + break; + } // case mtPig + + case mtSheep: + { + auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Sheep.IsBaby() ? -1 : (Sheep.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + + a_Pkt.WriteBEUInt8(0x10); + Byte SheepMetadata = 0; + SheepMetadata = static_cast<Byte>(Sheep.GetFurColor()); + if (Sheep.IsSheared()) + { + SheepMetadata |= 0x10; + } + a_Pkt.WriteBEUInt8(SheepMetadata); + break; + } // case mtSheep + + case mtRabbit: + { + auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob); + a_Pkt.WriteBEUInt8(0x12); + a_Pkt.WriteBEUInt8(static_cast<UInt8>(Rabbit.GetRabbitType())); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Rabbit.IsBaby() ? -1 : (Rabbit.GetBehaviorBreeder()->IsInLoveCooldown() ? 1 : 0)); + break; + } // case mtRabbit + + case mtSkeleton: + { + auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0d); + a_Pkt.WriteBEUInt8(Skeleton.IsWither() ? 1 : 0); + break; + } // case mtSkeleton + + case mtSlime: + { + auto & Slime = reinterpret_cast<const cSlime &>(a_Mob); + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(static_cast<UInt8>(Slime.GetSize())); + break; + } // case mtSlime + + case mtVillager: + { + auto & Villager = reinterpret_cast<const cVillager &>(a_Mob); + a_Pkt.WriteBEUInt8(0x50); + a_Pkt.WriteBEInt32(Villager.GetVilType()); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Villager.IsBaby() ? -1 : 0); + break; + } // case mtVillager + + case mtWitch: + { + auto & Witch = reinterpret_cast<const cWitch &>(a_Mob); + a_Pkt.WriteBEUInt8(0x15); + a_Pkt.WriteBEUInt8(Witch.IsAngry() ? 1 : 0); + break; + } // case mtWitch + + case mtWither: + { + auto & Wither = reinterpret_cast<const cWither &>(a_Mob); + a_Pkt.WriteBEUInt8(0x54); // Int at index 20 + a_Pkt.WriteBEInt32(static_cast<Int32>(Wither.GetWitherInvulnerableTicks())); + a_Pkt.WriteBEUInt8(0x66); // Float at index 6 + a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); + break; + } // case mtWither + + case mtWolf: + { + auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob); + Byte WolfStatus = 0; + if (Wolf.IsSitting()) + { + WolfStatus |= 0x1; + } + if (Wolf.IsAngry()) + { + WolfStatus |= 0x2; + } + if (Wolf.IsTame()) + { + WolfStatus |= 0x4; + } + a_Pkt.WriteBEUInt8(0x10); + a_Pkt.WriteBEUInt8(WolfStatus); + + a_Pkt.WriteBEUInt8(0x72); + a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); + a_Pkt.WriteBEUInt8(0x13); + a_Pkt.WriteBEUInt8(Wolf.IsBegging() ? 1 : 0); + a_Pkt.WriteBEUInt8(0x14); + a_Pkt.WriteBEUInt8(static_cast<UInt8>(Wolf.GetCollarColor())); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Wolf.IsBaby() ? -1 : 0); + break; + } // case mtWolf + + case mtZombie: + { + auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(Zombie.IsBaby() ? 1 : -1); + a_Pkt.WriteBEUInt8(0x0d); + a_Pkt.WriteBEUInt8(Zombie.IsVillagerZombie() ? 1 : 0); + a_Pkt.WriteBEUInt8(0x0e); + a_Pkt.WriteBEUInt8(Zombie.IsConverting() ? 1 : 0); + break; + } // case mtZombie + + case mtZombiePigman: + { + auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob); + a_Pkt.WriteBEUInt8(0x0c); + a_Pkt.WriteBEInt8(ZombiePigman.IsBaby() ? 1 : -1); + break; + } // case mtZombiePigman + } // switch (a_Mob.GetType()) } @@ -3648,18 +3648,18 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) { - if (!a_Entity.IsMob()) - { - // No properties for anything else than mobs - a_Pkt.WriteBEInt32(0); - return; - } + if (!a_Entity.IsMob()) + { + // No properties for anything else than mobs + a_Pkt.WriteBEInt32(0); + return; + } - // const cMonster & Mob = (const cMonster &)a_Entity; + // const cMonster & Mob = (const cMonster &)a_Entity; - // TODO: Send properties and modifiers based on the mob type + // TODO: Send properties and modifiers based on the mob type - a_Pkt.WriteBEInt32(0); // NumProperties + a_Pkt.WriteBEInt32(0); // NumProperties } |