190 lines
4.4 KiB
C++
190 lines
4.4 KiB
C++
|
|
// Protocol_1_11.cpp
|
|
|
|
/*
|
|
Implements the 1.11 protocol classes:
|
|
- cProtocol_1_11_0
|
|
- release 1.11 protocol (#315)
|
|
(others may be added later in the future for the 1.11 release series)
|
|
*/
|
|
|
|
#include "Globals.h"
|
|
#include "Protocol_1_11.h"
|
|
#include "ProtocolRecognizer.h"
|
|
#include "Packetizer.h"
|
|
|
|
#include "../Root.h"
|
|
#include "../Server.h"
|
|
#include "../ClientHandle.h"
|
|
#include "../CompositeChat.h"
|
|
#include "../Bindings/PluginManager.h"
|
|
#include "../Entities/Player.h"
|
|
#include "../Mobs/Monster.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define HANDLE_READ(ByteBuf, Proc, Type, Var) \
|
|
Type Var; \
|
|
if (!ByteBuf.Proc(Var))\
|
|
{\
|
|
return;\
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cProtocol_1_11_0::cProtocol_1_11_0(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) :
|
|
super(a_Client, a_ServerAddress, a_ServerPort, a_State)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int 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());
|
|
Pkt.WriteVarInt32(static_cast<UInt32>(a_Count));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::SendHideTitle(void)
|
|
{
|
|
ASSERT(m_State == 3); // In game mode?
|
|
|
|
cPacketizer Pkt(*this, 0x45); // Title packet
|
|
Pkt.WriteVarInt32(4); // Hide title
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::SendResetTitle(void)
|
|
{
|
|
ASSERT(m_State == 3); // In game mode?
|
|
|
|
cPacketizer Pkt(*this, 0x45); // Title packet
|
|
Pkt.WriteVarInt32(5); // Reset title
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob)
|
|
{
|
|
ASSERT(m_State == 3); // In game mode?
|
|
|
|
cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet
|
|
Pkt.WriteVarInt32(a_Mob.GetUniqueID());
|
|
Pkt.WriteVarInt32(static_cast<UInt32>(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
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
|
|
{
|
|
ASSERT(m_State == 3); // In game mode?
|
|
|
|
cPacketizer Pkt(*this, 0x45); // Title packet
|
|
Pkt.WriteVarInt32(3); // Set title display times
|
|
Pkt.WriteBEInt32(a_FadeInTicks);
|
|
Pkt.WriteBEInt32(a_DisplayTicks);
|
|
Pkt.WriteBEInt32(a_FadeOutTicks);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
|
|
{
|
|
int BlockX, BlockY, BlockZ;
|
|
if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ))
|
|
{
|
|
return;
|
|
}
|
|
|
|
HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Face);
|
|
HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Hand);
|
|
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorX);
|
|
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorY);
|
|
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorZ);
|
|
m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16), m_Client->GetPlayer()->GetEquippedItem());
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocol_1_11_0::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
|
|
{
|
|
cServer * Server = cRoot::Get()->GetServer();
|
|
AString ServerDescription = Server->GetDescription();
|
|
int NumPlayers = Server->GetNumPlayers();
|
|
int MaxPlayers = Server->GetMaxPlayers();
|
|
AString Favicon = Server->GetFaviconData();
|
|
cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
|
|
|
|
// Version:
|
|
Json::Value Version;
|
|
Version["name"] = "Cuberite 1.11";
|
|
Version["protocol"] = cProtocolRecognizer::PROTO_VERSION_1_11_0;
|
|
|
|
// Players:
|
|
Json::Value Players;
|
|
Players["online"] = NumPlayers;
|
|
Players["max"] = MaxPlayers;
|
|
// TODO: Add "sample"
|
|
|
|
// 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());
|
|
}
|
|
|
|
// Serialize the response into a packet:
|
|
Json::FastWriter Writer;
|
|
cPacketizer Pkt(*this, 0x00); // Response packet
|
|
Pkt.WriteString(Writer.write(ResponseValue));
|
|
}
|
|
|
|
|
|
|
|
|
|
|