1
0
Fork 0

Unify entity spawn packet sending

This commit is contained in:
Tiger Wang 2020-04-20 20:46:04 +01:00
parent dfe7a0adee
commit 0b9b7bc1a8
26 changed files with 242 additions and 464 deletions

View File

@ -2733,15 +2733,6 @@ void cClientHandle::SendParticleEffect(const AString & a_ParticleName, const Vec
void cClientHandle::SendPickupSpawn(const cPickup & a_Pickup)
{
m_Protocol->SendPickupSpawn(a_Pickup);
}
void cClientHandle::SendPaintingSpawn(const cPainting & a_Painting) void cClientHandle::SendPaintingSpawn(const cPainting & a_Painting)
{ {
m_Protocol->SendPaintingSpawn(a_Painting); m_Protocol->SendPaintingSpawn(a_Painting);
@ -3031,9 +3022,9 @@ void cClientHandle::SendSoundParticleEffect(const EffectID a_EffectID, int a_Src
void cClientHandle::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cClientHandle::SendSpawnEntity(const cEntity & a_Entity)
{ {
m_Protocol->SendSpawnFallingBlock(a_FallingBlock); m_Protocol->SendSpawnEntity(a_Entity);
} }
@ -3049,24 +3040,6 @@ void cClientHandle::SendSpawnMob(const cMonster & a_Mob)
void cClientHandle::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData)
{
m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData);
}
void cClientHandle::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) // VehicleSubType is specific to Minecarts
{
m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType);
}
void cClientHandle::SendStatistics(const cStatManager & a_Manager) void cClientHandle::SendStatistics(const cStatManager & a_Manager)
{ {
m_Protocol->SendStatistics(a_Manager); m_Protocol->SendStatistics(a_Manager);

View File

@ -166,7 +166,6 @@ public: // tolua_export
void SendEntityHeadLook (const cEntity & a_Entity); void SendEntityHeadLook (const cEntity & a_Entity);
void SendEntityLook (const cEntity & a_Entity); void SendEntityLook (const cEntity & a_Entity);
void SendEntityMetadata (const cEntity & a_Entity); void SendEntityMetadata (const cEntity & a_Entity);
void SendEntityProperties (const cEntity & a_Entity);
void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityStatus (const cEntity & a_Entity, char a_Status); void SendEntityStatus (const cEntity & a_Entity, char a_Status);
@ -184,7 +183,6 @@ public: // tolua_export
void SendPaintingSpawn (const cPainting & a_Painting); void SendPaintingSpawn (const cPainting & a_Painting);
void 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); void 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);
void SendParticleEffect (const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data); void SendParticleEffect (const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data);
void SendPickupSpawn (const cPickup & a_Pickup);
void SendPlayerAbilities (void); void SendPlayerAbilities (void);
void SendPlayerListAddPlayer (const cPlayer & a_Player); void SendPlayerListAddPlayer (const cPlayer & a_Player);
void SendPlayerListRemovePlayer (const cPlayer & a_Player); void SendPlayerListRemovePlayer (const cPlayer & a_Player);
@ -209,10 +207,8 @@ public: // tolua_export
void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export
void SendSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch); // tolua_export void SendSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch); // tolua_export
void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data);
void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); void SendSpawnEntity (const cEntity & a_Entity);
void SendSpawnMob (const cMonster & a_Mob); void SendSpawnMob (const cMonster & a_Mob);
void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData);
void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0);
void SendStatistics (const cStatManager & a_Manager); void SendStatistics (const cStatManager & a_Manager);
void SendTabCompletionResults (const AStringVector & a_Results); void SendTabCompletionResults (const AStringVector & a_Results);
void SendTeleportEntity (const cEntity & a_Entity); void SendTeleportEntity (const cEntity & a_Entity);

View File

@ -3,7 +3,6 @@
#include "Player.h" #include "Player.h"
#include "ArrowEntity.h" #include "ArrowEntity.h"
#include "../Chunk.h" #include "../Chunk.h"
#include "../ClientHandle.h"
@ -161,16 +160,6 @@ void cArrowEntity::CollectedBy(cPlayer & a_Dest)
void cArrowEntity::SpawnOn(cClientHandle & a_Client)
{
a_Client.SendSpawnObject(*this, m_ProjectileKind, static_cast<int>(m_CreatorData.m_UniqueID + 1));
a_Client.SendEntityMetadata(*this);
}
void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{ {
Super::Tick(a_Dt, a_Chunk); Super::Tick(a_Dt, a_Chunk);

View File

@ -108,7 +108,6 @@ protected:
virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override; virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override;
virtual void CollectedBy(cPlayer & a_Player) override; virtual void CollectedBy(cPlayer & a_Player) override;
virtual void SpawnOn(cClientHandle & a_Client) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
}; // tolua_export }; // tolua_export

View File

@ -33,7 +33,7 @@ cBoat::cBoat(Vector3d a_Pos, eMaterial a_Material) :
void cBoat::SpawnOn(cClientHandle & a_ClientHandle) void cBoat::SpawnOn(cClientHandle & a_ClientHandle)
{ {
a_ClientHandle.SendSpawnVehicle(*this, 1); a_ClientHandle.SendSpawnEntity(*this);
} }

View File

@ -22,7 +22,7 @@ cEnderCrystal::cEnderCrystal(Vector3d a_Pos):
void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle)
{ {
a_ClientHandle.SendSpawnObject(*this, 51, 0); a_ClientHandle.SendSpawnEntity(*this);
} }

View File

@ -26,7 +26,7 @@ cFallingBlock::cFallingBlock(Vector3d a_Position, BLOCKTYPE a_BlockType, NIBBLET
void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle)
{ {
a_ClientHandle.SendSpawnFallingBlock(*this); a_ClientHandle.SendSpawnEntity(*this);
} }

View File

@ -92,7 +92,7 @@ cFloater::cFloater(Vector3d a_Pos, Vector3d a_Speed, UInt32 a_PlayerID, int a_Co
void cFloater::SpawnOn(cClientHandle & a_Client) void cFloater::SpawnOn(cClientHandle & a_Client)
{ {
a_Client.SendSpawnObject(*this, 90, static_cast<int>(m_PlayerID)); a_Client.SendSpawnEntity(*this);
} }
@ -107,7 +107,7 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT)) if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT))
&& (m_World->GetBlockMeta(POSX_TOINT, POSY_TOINT, POSZ_TOINT) == 0)) && (m_World->GetBlockMeta(POSX_TOINT, POSY_TOINT, POSZ_TOINT) == 0))
{ {
if ((!m_CanPickupItem) && (m_AttachedMobID == cEntity::INVALID_ID)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob. if (!m_CanPickupItem && (m_AttachedMobID == cEntity::INVALID_ID)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob.
{ {
if (m_CountDownTime <= 0) if (m_CountDownTime <= 0)
{ {

View File

@ -95,10 +95,6 @@ void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer)
void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle) void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle)
{ {
Super::SpawnOn(a_ClientHandle); Super::SpawnOn(a_ClientHandle);
a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing()); a_ClientHandle.SendSpawnEntity(*this);
a_ClientHandle.SendEntityMetadata(*this); a_ClientHandle.SendEntityMetadata(*this);
} }

View File

@ -107,7 +107,7 @@ void cLeashKnot::GetDrops(cItems & a_Items, cEntity * a_Killer)
void cLeashKnot::SpawnOn(cClientHandle & a_ClientHandle) void cLeashKnot::SpawnOn(cClientHandle & a_ClientHandle)
{ {
Super::SpawnOn(a_ClientHandle); Super::SpawnOn(a_ClientHandle);
a_ClientHandle.SendSpawnObject(*this, 77, GetProtocolFacing()); a_ClientHandle.SendSpawnEntity(*this);
a_ClientHandle.SendEntityMetadata(*this); a_ClientHandle.SendEntityMetadata(*this);
} }

View File

@ -116,7 +116,7 @@ cMinecart::cMinecart(ePayload a_Payload, Vector3d a_Pos):
void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
{ {
a_ClientHandle.SendSpawnVehicle(*this, 10, static_cast<char>(m_Payload)); // 10 = Minecarts a_ClientHandle.SendSpawnEntity(*this);
a_ClientHandle.SendEntityMetadata(*this); a_ClientHandle.SendEntityMetadata(*this);
} }

View File

@ -118,7 +118,8 @@ cPickup::cPickup(Vector3d a_Pos, const cItem & a_Item, bool IsPlayerCreated, Vec
void cPickup::SpawnOn(cClientHandle & a_Client) void cPickup::SpawnOn(cClientHandle & a_Client)
{ {
a_Client.SendPickupSpawn(*this); a_Client.SendSpawnEntity(*this);
a_Client.SendEntityMetadata(*this);
} }

View File

@ -283,7 +283,6 @@ std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(
return cpp14::make_unique<cFireworkEntity>(a_Creator, a_Pos, *a_Item); return cpp14::make_unique<cFireworkEntity>(a_Creator, a_Pos, *a_Item);
} }
case pkFishingFloat: break;
} }
LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind); LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind);
@ -347,7 +346,6 @@ AString cProjectileEntity::GetMCAClassName(void) const
case pkSplashPotion: return "SplashPotion"; case pkSplashPotion: return "SplashPotion";
case pkWitherSkull: return "WitherSkull"; case pkWitherSkull: return "WitherSkull";
case pkFirework: return "Firework"; case pkFirework: return "Firework";
case pkFishingFloat: return ""; // Unknown, perhaps MC doesn't save this?
} }
UNREACHABLE("Unsupported projectile kind"); UNREACHABLE("Unsupported projectile kind");
} }
@ -443,8 +441,7 @@ void cProjectileEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a
void cProjectileEntity::SpawnOn(cClientHandle & a_Client) void cProjectileEntity::SpawnOn(cClientHandle & a_Client)
{ {
// Default spawning - use the projectile kind to spawn an object: a_Client.SendSpawnEntity(*this);
a_Client.SendSpawnObject(*this, m_ProjectileKind, 12);
a_Client.SendEntityMetadata(*this); a_Client.SendEntityMetadata(*this);
} }

View File

@ -29,20 +29,19 @@ class cProjectileEntity :
public: public:
/** The kind of the projectile. The numbers correspond to the network type ID used for spawning them in the protocol. */ /** The kind of the projectile. */
enum eKind enum eKind
{ {
pkArrow = 60, pkArrow,
pkSnowball = 61, pkSnowball,
pkEgg = 62, pkEgg,
pkGhastFireball = 63, pkGhastFireball,
pkFireCharge = 64, pkFireCharge,
pkEnderPearl = 65, pkEnderPearl,
pkExpBottle = 75, pkExpBottle,
pkSplashPotion = 73, pkSplashPotion,
pkFirework = 76, pkFirework,
pkWitherSkull = 66, pkWitherSkull,
pkFishingFloat = 90,
} ; } ;
// tolua_end // tolua_end
@ -93,7 +92,7 @@ public:
/** Returns the unique ID of the entity who created this projectile /** Returns the unique ID of the entity who created this projectile
May return an ID <0 May return an ID <0
*/ */
UInt32 GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; } UInt32 GetCreatorUniqueID(void) const { return m_CreatorData.m_UniqueID; }
/** Returns the name of the player that created the projectile /** Returns the name of the player that created the projectile
Will be empty for non-player creators Will be empty for non-player creators
@ -142,6 +141,6 @@ protected:
// cEntity overrides: // cEntity overrides:
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SpawnOn(cClientHandle & a_Client) override; virtual void SpawnOn(cClientHandle & a_Client) final override;
} ; // tolua_export } ; // tolua_export

View File

@ -2,7 +2,6 @@
#include "SplashPotionEntity.h" #include "SplashPotionEntity.h"
#include "Pawn.h" #include "Pawn.h"
#include "../ClientHandle.h"
#include "../EffectID.h" #include "../EffectID.h"
@ -89,17 +88,3 @@ void cSplashPotionEntity::Splash(Vector3d a_HitPos)
m_PotionColor m_PotionColor
); );
} }
void cSplashPotionEntity::SpawnOn(cClientHandle & a_Client)
{
a_Client.SendSpawnObject(*this, 73, m_PotionColor);
a_Client.SendEntityMetadata(*this);
}

View File

@ -84,8 +84,6 @@ protected:
@param a_HitPos The position where the potion will splash */ @param a_HitPos The position where the potion will splash */
void Splash(Vector3d a_HitPos); void Splash(Vector3d a_HitPos);
virtual void SpawnOn(cClientHandle & a_Client) override;
private: private:
/** Time in ticks to wait for the hit animation to begin before destroying */ /** Time in ticks to wait for the hit animation to begin before destroying */
int m_DestroyTimer; int m_DestroyTimer;

View File

@ -22,8 +22,8 @@ cTNTEntity::cTNTEntity(Vector3d a_Pos, int a_FuseTicks) :
void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle) void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle)
{ {
a_ClientHandle.SendSpawnObject(*this, 50, 1); // 50 means TNT a_ClientHandle.SendSpawnEntity(*this);
m_bDirtyOrientation = false; m_bDirtyOrientation = false; // TODO: why?
m_bDirtyHead = false; m_bDirtyHead = false;
} }

View File

@ -41,7 +41,7 @@ public:
} }
// Make sure block that will be occupied by the item frame is free now: // Make sure block that will be occupied by the item frame is free now:
auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace); const auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
BLOCKTYPE Block = a_World->GetBlock(PlacePos); BLOCKTYPE Block = a_World->GetBlock(PlacePos);
if (Block != E_BLOCK_AIR) if (Block != E_BLOCK_AIR)
{ {
@ -49,7 +49,7 @@ public:
} }
// Place the item frame: // Place the item frame:
auto ItemFrame = cpp14::make_unique<cItemFrame>(a_ClickedBlockFace, a_ClickedBlockPos); auto ItemFrame = cpp14::make_unique<cItemFrame>(a_ClickedBlockFace, PlacePos);
auto ItemFramePtr = ItemFrame.get(); auto ItemFramePtr = ItemFrame.get();
if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World)) if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World))
{ {

View File

@ -185,7 +185,6 @@ public:
virtual void SendLoginSuccess (void) = 0; virtual void SendLoginSuccess (void) = 0;
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) = 0; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) = 0;
virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0; virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0;
virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0;
virtual void SendPlayerAbilities (void) = 0; virtual void SendPlayerAbilities (void) = 0;
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0;
virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0;
@ -215,10 +214,8 @@ public:
virtual void SendSetRawTitle (const AString & a_Title) = 0; virtual void SendSetRawTitle (const AString & a_Title) = 0;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0;
virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; virtual void SendSpawnEntity (const cEntity & a_Entity) = 0;
virtual void SendSpawnMob (const cMonster & a_Mob) = 0; virtual void SendSpawnMob (const cMonster & a_Mob) = 0;
virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) = 0;
virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) = 0;
virtual void SendStatistics (const cStatManager & a_Manager) = 0; virtual void SendStatistics (const cStatManager & a_Manager) = 0;
virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0;
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
@ -259,9 +256,6 @@ protected:
/** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */ /** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */
virtual UInt32 GetPacketID(ePacketType a_Packet) = 0; virtual UInt32 GetPacketID(ePacketType a_Packet) = 0;
/** Converts eMonsterType to protocol-specific mob types */
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) = 0;
/** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */ /** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */
virtual void SendData(const char * a_Data, size_t a_Size) = 0; virtual void SendData(const char * a_Data, size_t a_Size) = 0;

View File

@ -550,16 +550,6 @@ void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting)
void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPickupSpawn(a_Pickup);
}
void cProtocolRecognizer::SendPlayerAbilities(void) void cProtocolRecognizer::SendPlayerAbilities(void)
{ {
ASSERT(m_Protocol != nullptr); ASSERT(m_Protocol != nullptr);
@ -830,10 +820,10 @@ void cProtocolRecognizer::SendSoundParticleEffect(const EffectID a_EffectID, int
void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cProtocolRecognizer::SendSpawnEntity(const cEntity & a_Entity)
{ {
ASSERT(m_Protocol != nullptr); ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnFallingBlock(a_FallingBlock); m_Protocol->SendSpawnEntity(a_Entity);
} }
@ -850,26 +840,6 @@ void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob)
void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData);
}
void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType);
}
void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager) void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager)
{ {
ASSERT(m_Protocol != nullptr); ASSERT(m_Protocol != nullptr);
@ -1020,15 +990,6 @@ AString cProtocolRecognizer::GetAuthServerID(void)
UInt32 cProtocolRecognizer::GetProtocolMobType(eMonsterType a_MobType)
{
return 0;
}
void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size) void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size)
{ {
// This is used only when handling the server ping // This is used only when handling the server ping

View File

@ -89,7 +89,6 @@ public:
virtual void 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) override; virtual void 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) override;
virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override; virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAbilities (void) override; virtual void SendPlayerAbilities (void) override;
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
@ -117,10 +116,8 @@ public:
virtual void SendSetRawTitle (const AString & a_Title) override; virtual void SendSetRawTitle (const AString & a_Title) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnEntity (const cEntity & a_Entity) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override;
virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override;
virtual void SendStatistics (const cStatManager & a_Manager) override; virtual void SendStatistics (const cStatManager & a_Manager) override;
virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
@ -156,9 +153,6 @@ protected:
/** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */ /** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */
virtual UInt32 GetPacketID(ePacketType a_PacketType) override; virtual UInt32 GetPacketID(ePacketType a_PacketType) override;
/** Converts eMonsterType to protocol-specific mob types */
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
// Packet handlers while in status state (m_InPingForUnrecognizedVersion == true) // Packet handlers while in status state (m_InPingForUnrecognizedVersion == true)
void HandlePacketStatusRequest(); void HandlePacketStatusRequest();
void HandlePacketStatusPing(); void HandlePacketStatusPing();

View File

@ -544,7 +544,7 @@ UInt32 cProtocol_1_11_0::GetProtocolMobType(eMonsterType a_MobType)
switch (a_MobType) switch (a_MobType)
{ {
// Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong) // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
case mtInvalidType: return 52; case mtInvalidType: return 53;
case mtBat: return 65; case mtBat: return 65;
case mtBlaze: return 61; case mtBlaze: return 61;
case mtCaveSpider: return 59; case mtCaveSpider: return 59;

View File

@ -31,6 +31,7 @@ Implements the 1.8 protocol classes:
#include "../Entities/ExpOrb.h" #include "../Entities/ExpOrb.h"
#include "../Entities/Minecart.h" #include "../Entities/Minecart.h"
#include "../Entities/FallingBlock.h" #include "../Entities/FallingBlock.h"
#include "../Entities/Floater.h"
#include "../Entities/Painting.h" #include "../Entities/Painting.h"
#include "../Entities/Pickup.h" #include "../Entities/Pickup.h"
#include "../Entities/Player.h" #include "../Entities/Player.h"
@ -852,28 +853,6 @@ 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?
{
cPacketizer Pkt(*this, pktSpawnObject);
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
}
SendEntityMetadata(a_Pickup);
}
void cProtocol_1_8_0::SendPlayerAbilities(void) void cProtocol_1_8_0::SendPlayerAbilities(void)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
@ -1370,23 +1349,45 @@ void cProtocol_1_8_0::SendSoundParticleEffect(const EffectID a_EffectID, int a_S
void cProtocol_1_8_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cProtocol_1_8_0::SendSpawnEntity(const cEntity & a_Entity)
{ {
ASSERT(m_State == 3); // In game mode? Int32 EntityData = /* Default: velocity present flag */ 1;
const auto EntityType = GetProtocolEntityType(a_Entity);
if (a_Entity.IsMinecart())
{
const auto & Cart = static_cast<const cMinecart &>(a_Entity);
EntityData = static_cast<Int32>(Cart.GetPayload());
}
else if (a_Entity.IsItemFrame())
{
const auto & Frame = static_cast<const cItemFrame &>(a_Entity);
EntityData = static_cast<Int32>(Frame.GetProtocolFacing());
}
else if (a_Entity.IsFallingBlock())
{
const auto & Block = static_cast<const cFallingBlock &>(a_Entity);
EntityData = Block.GetBlockType() | (static_cast<Int32>(Block.GetBlockMeta()) << 12);
}
else if (a_Entity.IsFloater())
{
const auto & Floater = static_cast<const cFloater &>(a_Entity);
EntityData = static_cast<Int32>(Floater.GetOwnerID());
}
else if (a_Entity.IsProjectile())
{
using PType = cProjectileEntity::eKind;
const auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
if (Projectile.GetProjectileKind() == PType::pkArrow)
{
const auto & Arrow = static_cast<const cArrowEntity &>(Projectile);
EntityData = static_cast<Int32>(Arrow.GetCreatorUniqueID() + 1);
}
}
cPacketizer Pkt(*this, pktSpawnObject); cPacketizer Pkt(*this, pktSpawnObject);
Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); WriteEntitySpawn(Pkt, a_Entity, EntityType, EntityData);
Pkt.WriteBEUInt8(70); // Falling block
Vector3d LastSentPos = a_FallingBlock.GetLastSentPos();
Pkt.WriteFPInt(LastSentPos.x);
Pkt.WriteFPInt(LastSentPos.y);
Pkt.WriteFPInt(LastSentPos.z);
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));
} }
@ -1418,64 +1419,6 @@ 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)
{
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, pktSpawnObject);
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));
}
}
void cProtocol_1_8_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, pktSpawnObject);
Pkt.WriteVarInt32(a_Vehicle.GetUniqueID());
Pkt.WriteBEUInt8(static_cast<UInt8>(a_VehicleType));
Vector3d LastSentPos = a_Vehicle.GetLastSentPos();
Pkt.WriteFPInt(LastSentPos.x);
Pkt.WriteFPInt(LastSentPos.y);
Pkt.WriteFPInt(LastSentPos.z);
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));
}
}
void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager) void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
@ -1808,70 +1751,70 @@ bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_Compr
int cProtocol_1_8_0::GetParticleID(const AString & a_ParticleName) int cProtocol_1_8_0::GetParticleID(const AString & a_ParticleName)
{ {
static std::map<AString, int> ParticleMap; static const std::unordered_map<AString, int> ParticleMap
if (ParticleMap.empty())
{ {
// Initialize the ParticleMap: // Initialize the ParticleMap:
ParticleMap["explode"] = 0; { "explode", 0 },
ParticleMap["largeexplode"] = 1; { "largeexplode", 1 },
ParticleMap["hugeexplosion"] = 2; { "hugeexplosion", 2 },
ParticleMap["fireworksspark"] = 3; { "fireworksspark", 3 },
ParticleMap["bubble"] = 4; { "bubble", 4 },
ParticleMap["splash"] = 5; { "splash", 5 },
ParticleMap["wake"] = 6; { "wake", 6 },
ParticleMap["suspended"] = 7; { "suspended", 7 },
ParticleMap["depthsuspend"] = 8; { "depthsuspend", 8 },
ParticleMap["crit"] = 9; { "crit", 9 },
ParticleMap["magiccrit"] = 10; { "magiccrit", 10 },
ParticleMap["smoke"] = 11; { "smoke", 11 },
ParticleMap["largesmoke"] = 12; { "largesmoke", 12 },
ParticleMap["spell"] = 13; { "spell", 13 },
ParticleMap["instantspell"] = 14; { "instantspell", 14 },
ParticleMap["mobspell"] = 15; { "mobspell", 15 },
ParticleMap["mobspellambient"] = 16; { "mobspellambient", 16 },
ParticleMap["witchmagic"] = 17; { "witchmagic", 17 },
ParticleMap["dripwater"] = 18; { "dripwater", 18 },
ParticleMap["driplava"] = 19; { "driplava", 19 },
ParticleMap["angryvillager"] = 20; { "angryvillager", 20 },
ParticleMap["happyvillager"] = 21; { "happyvillager", 21 },
ParticleMap["townaura"] = 22; { "townaura", 22 },
ParticleMap["note"] = 23; { "note", 23 },
ParticleMap["portal"] = 24; { "portal", 24 },
ParticleMap["enchantmenttable"] = 25; { "enchantmenttable", 25 },
ParticleMap["flame"] = 26; { "flame", 26 },
ParticleMap["lava"] = 27; { "lava", 27 },
ParticleMap["footstep"] = 28; { "footstep", 28 },
ParticleMap["cloud"] = 29; { "cloud", 29 },
ParticleMap["reddust"] = 30; { "reddust", 30 },
ParticleMap["snowballpoof"] = 31; { "snowballpoof", 31 },
ParticleMap["snowshovel"] = 32; { "snowshovel", 32 },
ParticleMap["slime"] = 33; { "slime", 33 },
ParticleMap["heart"] = 34; { "heart", 34 },
ParticleMap["barrier"] = 35; { "barrier", 35 },
ParticleMap["iconcrack"] = 36; { "iconcrack", 36 },
ParticleMap["blockcrack"] = 37; { "blockcrack", 37 },
ParticleMap["blockdust"] = 38; { "blockdust", 38 },
ParticleMap["droplet"] = 39; { "droplet", 39 },
ParticleMap["take"] = 40; { "take", 40 },
ParticleMap["mobappearance"] = 41; { "mobappearance", 41 },
ParticleMap["dragonbreath"] = 42; { "dragonbreath", 42 },
ParticleMap["endrod"] = 43; { "endrod", 43 },
ParticleMap["damageindicator"] = 44; { "damageindicator", 44 },
ParticleMap["sweepattack"] = 45; { "sweepattack", 45 },
ParticleMap["fallingdust"] = 46; { "fallingdust", 46 },
ParticleMap["totem"] = 47; { "totem", 47 },
ParticleMap["spit"] = 48; { "spit", 48 }
} };
AString ParticleName = StrToLower(a_ParticleName); const auto ParticleName = StrToLower(a_ParticleName);
if (ParticleMap.find(ParticleName) == ParticleMap.end()) const auto FindResult = ParticleMap.find(ParticleName);
if (FindResult == ParticleMap.end())
{ {
LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); LOGWARNING("Unknown particle: %s", a_ParticleName.c_str());
ASSERT(!"Unknown particle"); ASSERT(!"Unknown particle");
return 0; return 0;
} }
return ParticleMap[ParticleName]; return FindResult->second;
} }
@ -1883,7 +1826,7 @@ UInt32 cProtocol_1_8_0::GetProtocolMobType(eMonsterType a_MobType)
switch (a_MobType) switch (a_MobType)
{ {
// Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong) // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
case mtInvalidType: return 52; case mtInvalidType: return 53;
case mtBat: return 65; case mtBat: return 65;
case mtBlaze: return 61; case mtBlaze: return 61;
case mtCaveSpider: return 59; case mtCaveSpider: return 59;
@ -1925,41 +1868,6 @@ UInt32 cProtocol_1_8_0::GetProtocolMobType(eMonsterType a_MobType)
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;
}
}
}
void cProtocol_1_8_0::AddReceivedData(const char * a_Data, size_t a_Size) void cProtocol_1_8_0::AddReceivedData(const char * a_Data, size_t a_Size)
{ {
// Write the incoming data into the comm log file: // Write the incoming data into the comm log file:
@ -3918,3 +3826,76 @@ void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity &
a_Pkt.WriteBEInt32(0); // NumProperties a_Pkt.WriteBEInt32(0); // NumProperties
} }
void cProtocol_1_8_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
{
ASSERT(m_State == 3); // In game mode?
a_Pkt.WriteVarInt32(a_Entity.GetUniqueID());
a_Pkt.WriteBEUInt8(a_ObjectType);
a_Pkt.WriteFPInt(a_Entity.GetPosX());
a_Pkt.WriteFPInt(a_Entity.GetPosY());
a_Pkt.WriteFPInt(a_Entity.GetPosY());
a_Pkt.WriteByteAngle(a_Entity.GetPitch());
a_Pkt.WriteByteAngle(a_Entity.GetYaw());
a_Pkt.WriteBEInt32(a_ObjectData);
if (a_ObjectData != 0)
{
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
}
}
UInt8 cProtocol_1_8_0::GetProtocolEntityType(const cEntity & a_Entity)
{
using Type = cEntity::eEntityType;
switch (a_Entity.GetEntityType())
{
case Type::etEnderCrystal: return 51;
case Type::etPickup: return 2;
case Type::etFallingBlock: return 70;
case Type::etMinecart: return 10;
case Type::etBoat: return 1;
case Type::etTNT: return 50;
case Type::etProjectile:
{
using PType = cProjectileEntity::eKind;
const auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
switch (Projectile.GetProjectileKind())
{
case PType::pkArrow: return 60;
case PType::pkSnowball: return 61;
case PType::pkEgg: return 62;
case PType::pkGhastFireball: return 63;
case PType::pkFireCharge: return 64;
case PType::pkEnderPearl: return 65;
case PType::pkExpBottle: return 75;
case PType::pkSplashPotion: return 73;
case PType::pkFirework: return 76;
case PType::pkWitherSkull: return 66;
}
}
case Type::etFloater: return 90;
case Type::etItemFrame: return 71;
case Type::etLeashKnot: return 77;
// Non-objects must not be sent
case Type::etEntity:
case Type::etPlayer:
case Type::etMonster:
case Type::etExpOrb:
case Type::etPainting: UNREACHABLE("Tried to spawn an unhandled entity");
}
}

View File

@ -76,7 +76,6 @@ public:
virtual void SendLoginSuccess (void) override; virtual void SendLoginSuccess (void) override;
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAbilities (void) override; virtual void SendPlayerAbilities (void) override;
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
virtual void 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) override; virtual void 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) override;
@ -104,10 +103,8 @@ public:
virtual void SendSetTitle (const cCompositeChat & a_Title) override; virtual void SendSetTitle (const cCompositeChat & a_Title) override;
virtual void SendSetRawTitle (const AString & a_Title) override; virtual void SendSetRawTitle (const AString & a_Title) override;
virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnEntity (const cEntity & a_Entity) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override;
virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override;
virtual void SendStatistics (const cStatManager & a_Manager) override; virtual void SendStatistics (const cStatManager & a_Manager) override;
virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
@ -135,9 +132,6 @@ public:
/** The 1.8 protocol use a particle id instead of a string. This function converts the name to the id. If the name is incorrect, it returns 0. */ /** The 1.8 protocol use a particle id instead of a string. This function converts the name to the id. If the name is incorrect, it returns 0. */
static int GetParticleID(const AString & a_ParticleName); static int GetParticleID(const AString & a_ParticleName);
/** Minecraft 1.8 use other locations to spawn the item frame. This function converts the 1.7 positions to 1.8 positions. */
static void FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw);
protected: protected:
AString m_ServerAddress; AString m_ServerAddress;
@ -167,7 +161,7 @@ protected:
virtual UInt32 GetPacketID(ePacketType a_Packet) override; virtual UInt32 GetPacketID(ePacketType a_Packet) override;
/** Converts eMonsterType to protocol-specific mob types */ /** Converts eMonsterType to protocol-specific mob types */
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override; virtual UInt32 GetProtocolMobType(eMonsterType a_MobType);
/** Reads and handles the packet. The packet length and type have already been read. /** Reads and handles the packet. The packet length and type have already been read.
Returns true if the packet was understood, false if it was an unknown packet Returns true if the packet was understood, false if it was an unknown packet
@ -246,6 +240,15 @@ protected:
/** Writes the entity properties for the specified entity, including the Count field. */ /** Writes the entity properties for the specified entity, including the Count field. */
virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity); virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
/** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */
virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
/** Writes the block entity data for the specified block entity into the packet. */ /** Writes the block entity data for the specified block entity into the packet. */
virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity); virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity);
private:
/** Converts an entity to a protocol-specific entity type.
Only entities that the Send Spawn Entity packet supports are valid inputs to this method */
UInt8 GetProtocolEntityType(const cEntity & a_Entity);
} ; } ;

View File

@ -329,35 +329,6 @@ void cProtocol_1_9_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da
void cProtocol_1_9_0::SendPickupSpawn(const cPickup & a_Pickup)
{
ASSERT(m_State == 3); // In game mode?
{ // TODO Use SendSpawnObject
cPacketizer Pkt(*this, pktSpawnObject);
Pkt.WriteVarInt32(a_Pickup.GetUniqueID());
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
Pkt.WriteBEUInt64(0);
Pkt.WriteBEUInt64(a_Pickup.GetUniqueID());
Pkt.WriteBEUInt8(2); // Type = Pickup
Pkt.WriteBEDouble(a_Pickup.GetPosX());
Pkt.WriteBEDouble(a_Pickup.GetPosY());
Pkt.WriteBEDouble(a_Pickup.GetPosZ());
Pkt.WriteByteAngle(a_Pickup.GetYaw());
Pkt.WriteByteAngle(a_Pickup.GetPitch());
Pkt.WriteBEInt32(0); // No object data
Pkt.WriteBEInt16(0); // No velocity
Pkt.WriteBEInt16(0);
Pkt.WriteBEInt16(0);
}
SendEntityMetadata(a_Pickup);
}
void cProtocol_1_9_0::SendPlayerMaxSpeed(void) void cProtocol_1_9_0::SendPlayerMaxSpeed(void)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
@ -447,32 +418,6 @@ void cProtocol_1_9_0::SendSoundEffect(const AString & a_SoundName, double a_X, d
void cProtocol_1_9_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, pktSpawnObject);
Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID());
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
Pkt.WriteBEUInt64(0);
Pkt.WriteBEUInt64(a_FallingBlock.GetUniqueID());
Pkt.WriteBEUInt8(70); // Falling block
Vector3d LastSentPos = a_FallingBlock.GetLastSentPos();
Pkt.WriteBEDouble(LastSentPos.x);
Pkt.WriteBEDouble(LastSentPos.y);
Pkt.WriteBEDouble(LastSentPos.z);
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));
}
void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob) void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
@ -501,64 +446,6 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob)
void cProtocol_1_9_0::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData)
{
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, pktSpawnObject);
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
Pkt.WriteBEUInt64(0);
Pkt.WriteBEUInt64(a_Entity.GetUniqueID());
Pkt.WriteBEUInt8(static_cast<UInt8>(a_ObjectType));
Pkt.WriteBEDouble(PosX);
Pkt.WriteBEDouble(a_Entity.GetPosY());
Pkt.WriteBEDouble(PosZ);
Pkt.WriteByteAngle(a_Entity.GetPitch());
Pkt.WriteByteAngle(Yaw);
Pkt.WriteBEInt32(a_ObjectData);
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));
}
void cProtocol_1_9_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, pktSpawnObject);
Pkt.WriteVarInt32(a_Vehicle.GetUniqueID());
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
Pkt.WriteBEUInt64(0);
Pkt.WriteBEUInt64(a_Vehicle.GetUniqueID());
Pkt.WriteBEUInt8(static_cast<UInt8>(a_VehicleType));
Vector3d LastSentPos = a_Vehicle.GetLastSentPos();
Pkt.WriteBEDouble(LastSentPos.x);
Pkt.WriteBEDouble(LastSentPos.y);
Pkt.WriteBEDouble(LastSentPos.z);
Pkt.WriteByteAngle(a_Vehicle.GetPitch());
Pkt.WriteByteAngle(a_Vehicle.GetYaw());
Pkt.WriteBEInt32(a_VehicleSubType);
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));
}
void cProtocol_1_9_0::SendTeleportEntity(const cEntity & a_Entity) void cProtocol_1_9_0::SendTeleportEntity(const cEntity & a_Entity)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
@ -2286,6 +2173,32 @@ void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity &
void cProtocol_1_9_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
{
ASSERT(m_State == 3); // In game mode?
a_Pkt.WriteVarInt32(a_Entity.GetUniqueID());
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
a_Pkt.WriteBEUInt64(0);
a_Pkt.WriteBEUInt64(a_Entity.GetUniqueID());
a_Pkt.WriteBEUInt8(a_ObjectType);
a_Pkt.WriteBEDouble(a_Entity.GetPosX());
a_Pkt.WriteBEDouble(a_Entity.GetPosY());
a_Pkt.WriteBEDouble(a_Entity.GetPosZ());
a_Pkt.WriteByteAngle(a_Entity.GetPitch());
a_Pkt.WriteByteAngle(a_Entity.GetYaw());
a_Pkt.WriteBEInt32(a_ObjectData);
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_9_1: // cProtocol_1_9_1:

View File

@ -54,15 +54,11 @@ public:
virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override; virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override;
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMaxSpeed (void) override;
virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override;
virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void SendUnleashEntity (const cEntity & a_Entity) override; virtual void SendUnleashEntity (const cEntity & a_Entity) override;
@ -127,6 +123,9 @@ protected:
/** Writes the entity properties for the specified entity, including the Count field. */ /** Writes the entity properties for the specified entity, including the Count field. */
virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) override; virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
/** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */
virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override;
/** Writes the block entity data for the specified block entity into the packet. */ /** Writes the block entity data for the specified block entity into the packet. */
virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) override; virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) override;