summaryrefslogblamecommitdiffstats
path: root/source/Protocol/Protocol16x.cpp
blob: 8c93d605258e617fe04591fe6b8953253efce0cf (plain) (tree)




































                                                                     





                                         





































                                                                                         

















                                                                               































































                                                                                                                      

// Protocol16x.cpp

/*
Implements the 1.6.x protocol classes:
	- cProtocol161
		- release 1.6.1 protocol (#73)
(others may be added later in the future for the 1.6 release series)
*/

#include "Globals.h"
#include "Protocol16x.h"
#include "../ClientHandle.h"
#include "../Entity.h"
#include "../Player.h"





#define HANDLE_PACKET_READ(Proc, Type, Var) \
	Type Var; \
	{ \
		if (!m_ReceivedData.Proc(Var)) \
		{ \
			m_ReceivedData.CheckValid(); \
			return PARSE_INCOMPLETE; \
		} \
		m_ReceivedData.CheckValid(); \
	}





enum
{
	PACKET_CHAT              = 0x03,
	PACKET_UPDATE_HEALTH     = 0x08,
	PACKET_ATTACH_ENTITY     = 0x27,
	PACKET_ENTITY_PROPERTIES = 0x2c,
	PACKET_WINDOW_OPEN       = 0x64,
	PACKET_PLAYER_ABILITIES  = 0xca,
} ;






cProtocol161::cProtocol161(cClientHandle * a_Client) :
	super(a_Client)
{
}





void cProtocol161::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
{
	cCSLock Lock(m_CSPacket);
	WriteByte(PACKET_ATTACH_ENTITY);
	WriteInt(a_Entity.GetUniqueID());
	WriteInt((a_Vehicle == NULL) ? -1 : a_Vehicle->GetUniqueID());
	WriteBool(false);  // TODO: "Should use leash?" -> no
	Flush();
}





void cProtocol161::SendChat(const AString & a_Message)
{
	super::SendChat(Printf("{\"text\":\"%s\"}", a_Message.c_str()));
}




void cProtocol161::SendGameMode(eGameMode a_GameMode)
{
	super::SendGameMode(a_GameMode);
	
	// Also send the EntityProperties packet specifying the movementSpeed:
	cCSLock Lock(m_CSPacket);
	WriteByte(PACKET_ENTITY_PROPERTIES);
	WriteInt(m_Client->GetPlayer()->GetUniqueID());
	WriteInt(1);
	WriteString("generic.movementSpeed");
	WriteDouble(0.1);
	Flush();
}





void cProtocol161::SendHealth(void)
{
	cCSLock Lock(m_CSPacket);
	WriteByte (PACKET_UPDATE_HEALTH);
	WriteFloat((float)m_Client->GetPlayer()->GetHealth());
	WriteShort(m_Client->GetPlayer()->GetFoodLevel());
	WriteFloat(m_Client->GetPlayer()->GetFoodSaturationLevel());
	Flush();
}





void cProtocol161::SendWindowOpen(char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots)
{
	if (a_WindowType < 0)
	{
		// Do not send for inventory windows
		return;
	}
	cCSLock Lock(m_CSPacket);
	WriteByte  (PACKET_WINDOW_OPEN);
	WriteByte  (a_WindowID);
	WriteByte  (a_WindowType);
	WriteString(a_WindowTitle);
	WriteByte  (a_NumSlots);
	WriteByte  (1);  // Use title
	if (a_WindowType == 11)  // horse / donkey
	{
		WriteInt(0);  // Unknown value sent only when window type is 11 (horse / donkey)
	}
	Flush();
}





int cProtocol161::ParseEntityAction(void)
{
	HANDLE_PACKET_READ(ReadBEInt, int,  EntityID);
	HANDLE_PACKET_READ(ReadChar,  char, ActionID);
	HANDLE_PACKET_READ(ReadBEInt, int,  UnknownHorseVal);
	m_Client->HandleEntityAction(EntityID, ActionID);
	return PARSE_OK;
}





int cProtocol161::ParsePlayerAbilities(void)
{
	HANDLE_PACKET_READ(ReadByte,    Byte,  Flags);
	HANDLE_PACKET_READ(ReadBEFloat, float, FlyingSpeed);
	HANDLE_PACKET_READ(ReadBEFloat, float, WalkingSpeed);
	// TODO: m_Client->HandlePlayerAbilities(...);
	return PARSE_OK;
}