1
0

Almost all packets' handling is now rewritten not to use cPacket descendants elsewhere than in cClientHandle.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@761 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com
2012-08-19 19:42:32 +00:00
parent 5b36aa1567
commit 427e582d5f
40 changed files with 1089 additions and 507 deletions

View File

@@ -39,40 +39,45 @@
#include "cAuthenticator.h"
#include "MersenneTwister.h"
#include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_UpdateHealth.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_Chat.h"
#include "packets/cPacket_Login.h"
#include "packets/cPacket_TimeUpdate.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_Handshake.h"
#include "packets/cPacket_13.h"
#include "packets/cPacket_ArmAnim.h"
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_BlockPlace.h"
#include "packets/cPacket_Flying.h"
#include "packets/cPacket_Disconnect.h"
#include "packets/cPacket_PickupSpawn.h"
#include "packets/cPacket_ItemSwitch.h"
#include "packets/cPacket_EntityEquipment.h"
#include "packets/cPacket_Chat.h"
#include "packets/cPacket_CreativeInventoryAction.h"
#include "packets/cPacket_DestroyEntity.h"
#include "packets/cPacket_Disconnect.h"
#include "packets/cPacket_EntityEquipment.h"
#include "packets/cPacket_EntityLook.h"
#include "packets/cPacket_Flying.h"
#include "packets/cPacket_Handshake.h"
#include "packets/cPacket_InventorySlot.h"
#include "packets/cPacket_ItemSwitch.h"
#include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_Login.h"
#include "packets/cPacket_MapChunk.h"
#include "packets/cPacket_Metadata.h"
#include "packets/cPacket_MultiBlock.h"
#include "packets/cPacket_NamedEntitySpawn.h"
#include "packets/cPacket_NewInvalidState.h"
#include "packets/cPacket_PickupSpawn.h"
#include "packets/cPacket_Ping.h"
#include "packets/cPacket_Player.h"
#include "packets/cPacket_PreChunk.h"
#include "packets/cPacket_RelativeEntityMove.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_SpawnMob.h"
#include "packets/cPacket_TeleportEntity.h"
#include "packets/cPacket_TimeUpdate.h"
#include "packets/cPacket_UpdateHealth.h"
#include "packets/cPacket_UpdateSign.h"
#include "packets/cPacket_UseEntity.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_WindowClose.h"
#include "packets/cPacket_WindowOpen.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_13.h"
#include "packets/cPacket_UpdateSign.h"
#include "packets/cPacket_Ping.h"
#include "packets/cPacket_NamedEntitySpawn.h"
#include "packets/cPacket_MapChunk.h"
#include "packets/cPacket_PreChunk.h"
#include "packets/cPacket_InventorySlot.h"
// DEBUG:
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_MultiBlock.h"
@@ -500,6 +505,8 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
// Therefore I keep this function huge and untidy for the time being
// ( http://forum.mc-server.org/showthread.php?tid=524 )
// LOGD("Recv packet %02x", a_Packet->m_PacketID);
m_TimeLastPacket = cWorld::GetTime();
// LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str());
@@ -678,11 +685,35 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
HandleWindowClick(wc->m_WindowID, wc->m_SlotNum, wc->m_IsRightClick, wc->m_IsShiftPressed, wc->m_HeldItem);
break;
}
case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast<cPacket_UpdateSign *> (a_Packet)); break;
case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (a_Packet)); break;
case E_RESPAWN: HandleRespawn(); break;
case E_DISCONNECT: HandleDisconnect (reinterpret_cast<cPacket_Disconnect *> (a_Packet)); break;
case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast<cPacket_KeepAlive *> (a_Packet)); break;
case E_UPDATE_SIGN:
{
cPacket_UpdateSign * us = reinterpret_cast<cPacket_UpdateSign *>(a_Packet);
HandleUpdateSign(us->m_BlockX, us->m_BlockY, us->m_BlockZ, us->m_Line1, us->m_Line2, us->m_Line3, us->m_Line4);
break;
}
case E_USE_ENTITY:
{
cPacket_UseEntity * ue = reinterpret_cast<cPacket_UseEntity *>(a_Packet);
HandleUseEntity(ue->m_TargetEntityID, ue->m_IsLeftClick);
break;
}
case E_RESPAWN:
{
HandleRespawn();
break;
}
case E_DISCONNECT:
{
cPacket_Disconnect * dc = reinterpret_cast<cPacket_Disconnect *>(a_Packet);
HandleDisconnect(dc->m_Reason);
break;
}
case E_KEEP_ALIVE:
{
cPacket_KeepAlive * ka = reinterpret_cast<cPacket_KeepAlive *>(a_Packet);
HandleKeepAlive(ka->m_KeepAliveID);
break;
}
} // switch (Packet type)
break;
} // case csPlaying
@@ -797,7 +828,8 @@ void cClientHandle::HandleUnexpectedPacket(int a_PacketType)
void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ)
{
Vector3d ReceivedPosition = Vector3d(a_PosX, a_PosY, a_PosZ);
// LOGD("Received MoveLook confirmation: {%0.2f %0.2f %0.2f}", a_PosX, a_PosY, a_PosZ);
// Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up
double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength();
if (Dist < 1.0)
@@ -813,7 +845,7 @@ void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a
{
LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist);
m_ConfirmPosition = m_Player->GetPosition();
Send(cPacket_PlayerMoveLook(m_Player));
SendPlayerMoveLook();
}
}
@@ -840,8 +872,25 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel
void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround)
{
// LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
/*
// TODO: Invalid stance check
if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65))
{
LOGD("Invalid stance");
SendPlayerMoveLook();
return;
}
*/
// LOGD("recv player pos: {%0.2f %0.2f %0.2f}, ground: %d", a_PosX, a_PosY, a_PosZ, a_IsOnGround ? 1 : 0);
Vector3d Pos(a_PosX, a_PosY, a_PosZ);
if ((m_Player->GetPosition() - Pos).SqrLength() > 100 * 100)
{
LOGD("Too far away (%0.2f), \"repairing\" the client", (m_Player->GetPosition() - Pos).Length());
SendPlayerMoveLook();
return;
}
m_Player->MoveTo(Pos);
m_Player->SetStance(a_Stance);
m_Player->SetTouchGround(a_IsOnGround);
}
@@ -1086,6 +1135,16 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround)
{
/*
// TODO: Invalid stance check
if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65))
{
LOGD("Invalid stance");
SendPlayerMoveLook();
return;
}
*/
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
m_Player->SetStance (a_Stance);
m_Player->SetTouchGround(a_IsOnGround);
@@ -1148,20 +1207,25 @@ void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, bool a_I
void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet)
void cClientHandle::HandleUpdateSign(
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
)
{
cWorld * World = m_Player->GetWorld();
World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4);
World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
}
void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick)
{
if (!a_Packet->m_bLeftClick)
if (!a_IsLeftClick)
{
// TODO: we don't handle right-clicking yet
return;
}
@@ -1169,9 +1233,9 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
{
virtual bool Item(cEntity * a_Entity) override
{
if( a_Entity->IsA("cPawn") )
if (a_Entity->IsA("cPawn"))
{
reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator );
reinterpret_cast<cPawn *>(a_Entity)->TakeDamage(Damage, Instigator);
}
return true;
}
@@ -1184,7 +1248,7 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
Callback.Instigator = m_Player;
cWorld * World = m_Player->GetWorld();
World->DoWithEntityByID(a_Packet->m_TargetID, Callback);
World->DoWithEntityByID(a_TargetEntityID, Callback);
}
@@ -1200,13 +1264,14 @@ void cClientHandle::HandleRespawn(void)
void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet)
void cClientHandle::HandleDisconnect(const AString & a_Reason)
{
LOG("Received d/c packet from \"%s\"", m_Username.c_str());
if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player))
LOGD("Received d/c packet from \"%s\" with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason))
{
cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason);
cRoot::Get()->GetServer()->Broadcast(DisconnectMessage);
AString DisconnectMessage;
Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str());
m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this);
}
Destroy();
}
@@ -1215,9 +1280,9 @@ void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet)
void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
void cClientHandle::HandleKeepAlive(int a_KeepAliveID)
{
if (a_Packet->m_KeepAliveID == m_PingID)
if (a_KeepAliveID == m_PingID)
{
cTimer t1;
m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2);
@@ -1225,6 +1290,9 @@ void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
}
bool cClientHandle::CheckBlockInteractionsRate(void)
{
ASSERT(m_Player != NULL);
@@ -1543,6 +1611,174 @@ void cClientHandle::SendWholeInventory(const cWindow & a_Window)
void cClientHandle::SendTeleportEntity(const cEntity & a_Entity)
{
cPacket_TeleportEntity te(a_Entity);
Send(te);
}
void cClientHandle::SendPlayerListItem(const cPlayer & a_Player)
{
cPacket_PlayerListItem pli(a_Player.GetColor() + a_Player.GetName(), true, a_Player.GetClientHandle()->GetPing());
Send(pli);
}
void cClientHandle::SendPlayerPosition(void)
{
cPacket_PlayerPosition pp(m_Player);
Send(pp);
}
void cClientHandle::SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_RelativeEntityMoveLook reml;
reml.m_UniqueID = a_Entity.GetUniqueID();
reml.m_MoveX = a_RelX;
reml.m_MoveY = a_RelY;
reml.m_MoveZ = a_RelZ;
reml.m_Yaw = (char)((a_Entity.GetRotation() / 360.f) * 256);
reml.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
Send(reml);
}
void cClientHandle::SendRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_RelativeEntityMove rem;
rem.m_UniqueID = a_Entity.GetUniqueID();
rem.m_MoveX = a_RelX;
rem.m_MoveY = a_RelY;
rem.m_MoveZ = a_RelZ;
Send(rem);
}
void cClientHandle::SendEntLook(const cEntity & a_Entity)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_EntityLook el;
el.m_UniqueID = a_Entity.GetUniqueID();
el.m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256);
el.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
Send(el);
}
void cClientHandle::SendEntHeadLook(const cEntity & a_Entity)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_EntityHeadLook ehl(a_Entity);
Send(ehl);
}
void cClientHandle::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2)
{
cPacket_BlockAction ba;
ba.m_BlockX = a_BlockX;
ba.m_BlockY = (short)a_BlockY;
ba.m_BlockZ = a_BlockZ;
ba.m_Byte1 = a_Byte1;
ba.m_Byte2 = a_Byte2;
Send(ba);
}
void cClientHandle::SendHealth(void)
{
cPacket_UpdateHealth Health;
Health.m_Health = m_Player->GetHealth();
Health.m_Food = m_Player->GetFoodLevel();
Health.m_Saturation = m_Player->GetFoodSaturationLevel();
Send(Health);
}
void cClientHandle::SendRespawn(void)
{
cPacket_Respawn Packet;
Packet.m_CreativeMode = (char)m_Player->GetGameMode(); // Set GameMode packet based on Player's GameMode;
Send(Packet);
}
void cClientHandle::SendGameMode(char a_GameMode)
{
cPacket_NewInvalidState nis;
nis.m_Reason = 3;
nis.m_GameMode = a_GameMode;
Send(nis);
}
void cClientHandle::SendDestroyEntity(const cEntity & a_Entity)
{
cPacket_DestroyEntity de;
de.m_UniqueID = a_Entity.GetUniqueID();
Send(de);
}
void cClientHandle::SendPlayerMoveLook(void)
{
cPacket_PlayerMoveLook pml(*m_Player);
/*
LOGD("Sending PlayerMoveLook: {%0.2f, %0.2f, %0.2f}, stance %0.2f, OnGround: %d",
m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ(), m_Player->GetStance(), m_Player->IsOnGround() ? 1 : 0
);
*/
Send(pml);
}
void cClientHandle::CheckIfWorldDownloaded(void)
{
if (m_State != csDownloadingWorld)
@@ -1576,7 +1812,7 @@ void cClientHandle::SendConfirmPosition(void)
}
m_ConfirmPosition = m_Player->GetPosition();
Send(cPacket_PlayerMoveLook(m_Player));
SendPlayerMoveLook();
}
@@ -1808,6 +2044,7 @@ void cClientHandle::GetOutgoingData(AString & a_Data)
while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000))
{
m_PendingNrmSendPackets.front()->Serialize(Data);
// LOGD("Sending packet 0x%02x", m_PendingNrmSendPackets.front()->m_PacketID);
delete m_PendingNrmSendPackets.front();
m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin());
}