Merge branch 'master' into MobSpawner
Conflicts: src/MobSpawner.h src/Mobs/Monster.h
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
|
||||
// Protocol17x.cpp
|
||||
|
||||
/*
|
||||
Implements the 1.7.x protocol classes:
|
||||
- cProtocol172
|
||||
- release 1.7.2 protocol (#4)
|
||||
(others may be added later in the future for the 1.7 release series)
|
||||
- cProtocol176
|
||||
- release 1.7.6 protocol (#5)
|
||||
*/
|
||||
|
||||
#include "Globals.h"
|
||||
@@ -251,101 +253,13 @@ void cProtocol172::SendChat(const AString & a_Message)
|
||||
void cProtocol172::SendChat(const cCompositeChat & a_Message)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
// Compose the complete Json string to send:
|
||||
Json::Value msg;
|
||||
|
||||
cWorld * World = m_Client->GetPlayer()->GetWorld();
|
||||
msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present
|
||||
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
||||
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
||||
{
|
||||
Json::Value Part;
|
||||
switch ((*itr)->m_PartType)
|
||||
{
|
||||
case cCompositeChat::ptText:
|
||||
{
|
||||
Part["text"] = (*itr)->m_Text;
|
||||
AddChatPartStyle(Part, (*itr)->m_Style);
|
||||
break;
|
||||
}
|
||||
|
||||
case cCompositeChat::ptClientTranslated:
|
||||
{
|
||||
const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
|
||||
Part["translate"] = p.m_Text;
|
||||
Json::Value With;
|
||||
for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
|
||||
{
|
||||
With.append(*itrW);
|
||||
}
|
||||
if (!p.m_Parameters.empty())
|
||||
{
|
||||
Part["with"] = With;
|
||||
}
|
||||
AddChatPartStyle(Part, p.m_Style);
|
||||
break;
|
||||
}
|
||||
|
||||
case cCompositeChat::ptUrl:
|
||||
{
|
||||
const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
|
||||
Part["text"] = p.m_Text;
|
||||
Json::Value Url;
|
||||
Url["action"] = "open_url";
|
||||
Url["value"] = p.m_Url;
|
||||
Part["clickEvent"] = Url;
|
||||
AddChatPartStyle(Part, p.m_Style);
|
||||
break;
|
||||
}
|
||||
|
||||
case cCompositeChat::ptSuggestCommand:
|
||||
case cCompositeChat::ptRunCommand:
|
||||
{
|
||||
const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
|
||||
Part["text"] = p.m_Text;
|
||||
Json::Value Cmd;
|
||||
Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
|
||||
Cmd["value"] = p.m_Command;
|
||||
Part["clickEvent"] = Cmd;
|
||||
AddChatPartStyle(Part, p.m_Style);
|
||||
break;
|
||||
}
|
||||
bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes();
|
||||
|
||||
case cCompositeChat::ptShowAchievement:
|
||||
{
|
||||
const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
|
||||
Part["translate"] = "chat.type.achievement";
|
||||
|
||||
Json::Value Ach;
|
||||
Ach["action"] = "show_achievement";
|
||||
Ach["value"] = p.m_Text;
|
||||
|
||||
Json::Value AchColourAndName;
|
||||
AchColourAndName["color"] = "green";
|
||||
AchColourAndName["translate"] = p.m_Text;
|
||||
AchColourAndName["hoverEvent"] = Ach;
|
||||
|
||||
Json::Value Extra;
|
||||
Extra.append(AchColourAndName);
|
||||
|
||||
Json::Value Name;
|
||||
Name["text"] = p.m_PlayerName;
|
||||
|
||||
Json::Value With;
|
||||
With.append(Name);
|
||||
With.append(Extra);
|
||||
|
||||
Part["with"] = With;
|
||||
AddChatPartStyle(Part, p.m_Style);
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg["extra"].append(Part);
|
||||
} // for itr - Parts[]
|
||||
|
||||
// Send the message to the client:
|
||||
cPacketizer Pkt(*this, 0x02);
|
||||
Pkt.WriteString(msg.toStyledString());
|
||||
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
|
||||
}
|
||||
|
||||
|
||||
@@ -358,7 +272,7 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
|
||||
|
||||
// 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_3_2);
|
||||
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ);
|
||||
|
||||
cPacketizer Pkt(*this, 0x21); // Chunk Data packet
|
||||
Pkt.WriteInt(a_ChunkX);
|
||||
@@ -727,7 +641,7 @@ void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting)
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length)
|
||||
void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
@@ -749,7 +663,7 @@ void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
|
||||
void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
@@ -787,7 +701,6 @@ void cProtocol172::SendMapInfo(int a_ID, unsigned int a_Scale)
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
@@ -858,7 +771,7 @@ void cProtocol172::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio
|
||||
|
||||
|
||||
|
||||
void cProtocol172::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_ParticleAmmount)
|
||||
void cProtocol172::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?
|
||||
|
||||
@@ -871,21 +784,66 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr
|
||||
Pkt.WriteFloat(a_OffsetY);
|
||||
Pkt.WriteFloat(a_OffsetZ);
|
||||
Pkt.WriteFloat(a_ParticleData);
|
||||
Pkt.WriteInt(a_ParticleAmmount);
|
||||
Pkt.WriteInt(a_ParticleAmount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline)
|
||||
void cProtocol172::SendPlayerListAddPlayer(const cPlayer & a_Player)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
|
||||
cPacketizer Pkt(*this, 0x38); // Playerlist Item packet
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
Pkt.WriteBool(a_IsOnline);
|
||||
Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0);
|
||||
Pkt.WriteString(a_Player.GetPlayerListName());
|
||||
Pkt.WriteBool(true);
|
||||
Pkt.WriteShort(a_Player.GetClientHandle()->GetPing());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPlayerListRemovePlayer(const cPlayer & a_Player)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, 0x38);
|
||||
Pkt.WriteString(a_Player.GetPlayerListName());
|
||||
Pkt.WriteBool(false);
|
||||
Pkt.WriteShort(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPlayerListUpdateGameMode(const cPlayer & a_Player)
|
||||
{
|
||||
// Not implemented in this protocol version
|
||||
UNUSED(a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPlayerListUpdatePing(const cPlayer & a_Player)
|
||||
{
|
||||
// It is a simple add player packet in this protocol.
|
||||
SendPlayerListAddPlayer(a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName)
|
||||
{
|
||||
// Not implemented in this protocol version
|
||||
UNUSED(a_Player);
|
||||
UNUSED(a_CustomName);
|
||||
}
|
||||
|
||||
|
||||
@@ -959,9 +917,16 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
|
||||
// Called to spawn another player for the client
|
||||
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
|
||||
Pkt.WriteVarInt(a_Player.GetUniqueID());
|
||||
Pkt.WriteVarInt((UInt32) a_Player.GetUniqueID());
|
||||
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID()));
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
if (a_Player.HasCustomName())
|
||||
{
|
||||
Pkt.WriteString(a_Player.GetCustomName());
|
||||
}
|
||||
else
|
||||
{
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
}
|
||||
Pkt.WriteFPInt(a_Player.GetPosX());
|
||||
Pkt.WriteFPInt(a_Player.GetPosY());
|
||||
Pkt.WriteFPInt(a_Player.GetPosZ());
|
||||
@@ -1515,14 +1480,14 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
);
|
||||
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 (;;)
|
||||
{
|
||||
@@ -1542,10 +1507,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
cByteBuffer bb(PacketLen + 1);
|
||||
VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen));
|
||||
m_ReceivedData.CommitRead();
|
||||
|
||||
// Write one NUL extra, so that we can detect over-reads
|
||||
bb.Write("\0", 1);
|
||||
|
||||
|
||||
UInt32 PacketType;
|
||||
if (!bb.ReadVarInt(PacketType))
|
||||
{
|
||||
@@ -1553,6 +1515,9 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
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)
|
||||
{
|
||||
@@ -1560,7 +1525,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
bb.ReadAll(PacketData);
|
||||
bb.ResetRead();
|
||||
bb.ReadVarInt(PacketType);
|
||||
ASSERT(PacketData.size() > 0);
|
||||
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);
|
||||
@@ -1568,7 +1533,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
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:
|
||||
@@ -1593,7 +1558,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (bb.GetReadableSpace() != 1)
|
||||
{
|
||||
// Read more or less than packet length, report as error
|
||||
@@ -1614,7 +1579,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
||||
m_Client->PacketError(PacketType);
|
||||
}
|
||||
} // for (ever)
|
||||
|
||||
|
||||
// Log any leftover bytes into the logfile:
|
||||
if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0))
|
||||
{
|
||||
@@ -1725,7 +1690,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
|
||||
void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer)
|
||||
{
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp);
|
||||
|
||||
|
||||
cPacketizer Pkt(*this, 0x01); // Ping packet
|
||||
Pkt.WriteInt64(Timestamp);
|
||||
}
|
||||
@@ -1937,7 +1902,7 @@ void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
|
||||
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape);
|
||||
|
||||
m_Client->SetLocale(Locale);
|
||||
// TODO: handle in m_Client
|
||||
// TODO: Do anything with the other values.
|
||||
}
|
||||
|
||||
|
||||
@@ -2291,7 +2256,6 @@ void cProtocol172::SendData(const char * a_Data, size_t a_Size)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
|
||||
{
|
||||
HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType);
|
||||
@@ -2436,85 +2400,6 @@ void cProtocol172::StartEncryption(const Byte * a_Key)
|
||||
|
||||
|
||||
|
||||
void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle)
|
||||
{
|
||||
size_t len = a_PartStyle.length();
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
switch (a_PartStyle[i])
|
||||
{
|
||||
case 'b':
|
||||
{
|
||||
// bold
|
||||
a_Value["bold"] = Json::Value(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
{
|
||||
// italic
|
||||
a_Value["italic"] = Json::Value(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'u':
|
||||
{
|
||||
// Underlined
|
||||
a_Value["underlined"] = Json::Value(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
// strikethrough
|
||||
a_Value["strikethrough"] = Json::Value(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'o':
|
||||
{
|
||||
// obfuscated
|
||||
a_Value["obfuscated"] = Json::Value(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case '@':
|
||||
{
|
||||
// Color, specified by the next char:
|
||||
i++;
|
||||
if (i >= len)
|
||||
{
|
||||
// String too short, didn't contain a color
|
||||
break;
|
||||
}
|
||||
switch (a_PartStyle[i])
|
||||
{
|
||||
case '0': a_Value["color"] = Json::Value("black"); break;
|
||||
case '1': a_Value["color"] = Json::Value("dark_blue"); break;
|
||||
case '2': a_Value["color"] = Json::Value("dark_green"); break;
|
||||
case '3': a_Value["color"] = Json::Value("dark_aqua"); break;
|
||||
case '4': a_Value["color"] = Json::Value("dark_red"); break;
|
||||
case '5': a_Value["color"] = Json::Value("dark_purple"); break;
|
||||
case '6': a_Value["color"] = Json::Value("gold"); break;
|
||||
case '7': a_Value["color"] = Json::Value("gray"); break;
|
||||
case '8': a_Value["color"] = Json::Value("dark_gray"); break;
|
||||
case '9': a_Value["color"] = Json::Value("blue"); break;
|
||||
case 'a': a_Value["color"] = Json::Value("green"); break;
|
||||
case 'b': a_Value["color"] = Json::Value("aqua"); break;
|
||||
case 'c': a_Value["color"] = Json::Value("red"); break;
|
||||
case 'd': a_Value["color"] = Json::Value("light_purple"); break;
|
||||
case 'e': a_Value["color"] = Json::Value("yellow"); break;
|
||||
case 'f': a_Value["color"] = Json::Value("white"); break;
|
||||
} // switch (color)
|
||||
} // case '@'
|
||||
} // switch (Style[i])
|
||||
} // for i - a_PartStyle[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cProtocol172::cPacketizer:
|
||||
|
||||
@@ -2524,6 +2409,7 @@ cProtocol172::cPacketizer::~cPacketizer()
|
||||
|
||||
// Send the packet length
|
||||
UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace();
|
||||
|
||||
m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen);
|
||||
m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend);
|
||||
m_Protocol.SendData(DataToSend.data(), DataToSend.size());
|
||||
@@ -2618,6 +2504,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
||||
cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType);
|
||||
}
|
||||
Writer.Finish();
|
||||
|
||||
AString Compressed;
|
||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||
WriteShort((short)Compressed.size());
|
||||
@@ -2627,6 +2514,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEntity)
|
||||
{
|
||||
cFastNBTWriter Writer;
|
||||
@@ -2850,7 +2738,7 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity)
|
||||
WriteByte(0xA2);
|
||||
WriteItem(Frame.GetItem());
|
||||
WriteByte(0x3);
|
||||
WriteByte(Frame.GetRotation());
|
||||
WriteByte(Frame.GetRotation() / 2);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
@@ -2865,7 +2753,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
{
|
||||
switch (a_Mob.GetMobType())
|
||||
{
|
||||
case cMonster::mtCreeper:
|
||||
case mtCreeper:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1);
|
||||
@@ -2874,28 +2762,28 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtBat:
|
||||
case mtBat:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtPig:
|
||||
case mtPig:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtVillager:
|
||||
case mtVillager:
|
||||
{
|
||||
WriteByte(0x50);
|
||||
WriteInt(((const cVillager &)a_Mob).GetVilType());
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtZombie:
|
||||
case mtZombie:
|
||||
{
|
||||
WriteByte(0x0c);
|
||||
WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0);
|
||||
@@ -2906,14 +2794,14 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtGhast:
|
||||
case mtGhast:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cGhast &)a_Mob).IsCharging());
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtWolf:
|
||||
case mtWolf:
|
||||
{
|
||||
const cWolf & Wolf = (const cWolf &)a_Mob;
|
||||
Byte WolfStatus = 0;
|
||||
@@ -2941,7 +2829,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtSheep:
|
||||
case mtSheep:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
Byte SheepMetadata = 0;
|
||||
@@ -2954,7 +2842,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtEnderman:
|
||||
case mtEnderman:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock()));
|
||||
@@ -2965,21 +2853,21 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtSkeleton:
|
||||
case mtSkeleton:
|
||||
{
|
||||
WriteByte(0x0d);
|
||||
WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtWitch:
|
||||
case mtWitch:
|
||||
{
|
||||
WriteByte(0x15);
|
||||
WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtWither:
|
||||
case mtWither:
|
||||
{
|
||||
WriteByte(0x54); // Int at index 20
|
||||
WriteInt(((const cWither &)a_Mob).GetWitherInvulnerableTicks());
|
||||
@@ -2988,21 +2876,21 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtSlime:
|
||||
case mtSlime:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cSlime &)a_Mob).GetSize());
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtMagmaCube:
|
||||
case mtMagmaCube:
|
||||
{
|
||||
WriteByte(0x10);
|
||||
WriteByte(((const cMagmaCube &)a_Mob).GetSize());
|
||||
break;
|
||||
}
|
||||
|
||||
case cMonster::mtHorse:
|
||||
case mtHorse:
|
||||
{
|
||||
const cHorse & Horse = (const cHorse &)a_Mob;
|
||||
int Flags = 0;
|
||||
@@ -3048,6 +2936,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
||||
break;
|
||||
}
|
||||
} // switch (a_Mob.GetType())
|
||||
|
||||
// Custom name:
|
||||
if (a_Mob.HasCustomName())
|
||||
{
|
||||
WriteByte(0x8a);
|
||||
WriteString(a_Mob.GetCustomName());
|
||||
WriteByte(0x0b);
|
||||
WriteByte(a_Mob.IsCustomNameAlwaysVisible() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3092,7 +2989,14 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
|
||||
Pkt.WriteVarInt(a_Player.GetUniqueID());
|
||||
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID()));
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
if (a_Player.HasCustomName())
|
||||
{
|
||||
Pkt.WriteString(a_Player.GetCustomName());
|
||||
}
|
||||
else
|
||||
{
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
}
|
||||
|
||||
const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties();
|
||||
Pkt.WriteVarInt(Properties.size());
|
||||
|
||||
Reference in New Issue
Block a user