From f5fe723b2a704da475b24a594fd59f448cf133a3 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Thu, 30 Aug 2012 09:56:59 +0000 Subject: [PATCH] Added a basic protocol recognizer and the base for 1.3.2 protocol. Also fixed a few type-related warnings. git-svn-id: http://mc-server.googlecode.com/svn/trunk@805 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2008/MCServer.vcproj | 12 + VC2010/MCServer.vcxproj | 3 + VC2010/MCServer.vcxproj.filters | 9 + source/Protocol.h | 2 +- source/Protocol125.cpp | 6 +- source/Protocol125.h | 2 +- source/Protocol132.cpp | 65 ++++ source/Protocol132.h | 35 +++ source/ProtocolRecognizer.cpp | 522 ++++++++++++++++++++++++++++++++ source/ProtocolRecognizer.h | 23 +- source/cChatColor.cpp | 4 +- source/cClientHandle.cpp | 35 +-- source/cClientHandle.h | 4 +- source/cCraftingWindow.cpp | 2 +- 14 files changed, 682 insertions(+), 42 deletions(-) create mode 100644 source/Protocol132.cpp create mode 100644 source/Protocol132.h create mode 100644 source/ProtocolRecognizer.cpp diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 74dc07322..d1707a45b 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -2023,6 +2023,18 @@ RelativePath="..\source\Protocol125.h" > + + + + + + diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index abf8276e9..0ff22287c 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -441,6 +441,8 @@ + + @@ -646,6 +648,7 @@ + diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index e8e135db2..fb7d013b3 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -667,6 +667,12 @@ Protocol + + Protocol + + + Protocol + @@ -1236,6 +1242,9 @@ Protocol + + Protocol + diff --git a/source/Protocol.h b/source/Protocol.h index c87516640..2b6bdd561 100644 --- a/source/Protocol.h +++ b/source/Protocol.h @@ -58,7 +58,7 @@ public: virtual void SendGameMode (eGameMode a_GameMode) = 0; virtual void SendHealth (void) = 0; virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) = 0; - virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) = 0; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) = 0; virtual void SendKeepAlive (int a_PingID) = 0; virtual void SendLogin (const cPlayer & a_Player) = 0; virtual void SendMetadata (const cEntity & a_Entity) = 0; diff --git a/source/Protocol125.cpp b/source/Protocol125.cpp index a50551c35..ce86e70c4 100644 --- a/source/Protocol125.cpp +++ b/source/Protocol125.cpp @@ -133,7 +133,7 @@ void cProtocol125::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO cCSLock Lock(m_CSPacket); WriteByte(PACKET_BLOCK_CHANGE); WriteInt (a_BlockX); - WriteByte(a_BlockY); + WriteByte((unsigned char)a_BlockY); WriteInt (a_BlockZ); WriteByte(a_BlockType); WriteByte(a_BlockMeta); @@ -354,7 +354,7 @@ void cProtocol125::SendInventoryProgress(char a_WindowID, short a_ProgressBar, s -void cProtocol125::SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item) +void cProtocol125::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { cCSLock Lock(m_CSPacket); WriteByte (PACKET_INVENTORY_SLOT); @@ -716,7 +716,7 @@ void cProtocol125::SendWholeInventory(const cWindow & a_Window) { cCSLock Lock(m_CSPacket); SendWholeInventory( - a_Window.GetWindowID(), + (char)a_Window.GetWindowID(), a_Window.GetNumSlots(), a_Window.GetSlots() ); diff --git a/source/Protocol125.h b/source/Protocol125.h index db2b88833..3e0535163 100644 --- a/source/Protocol125.h +++ b/source/Protocol125.h @@ -44,7 +44,7 @@ public: virtual void SendGameMode (eGameMode a_GameMode) override; virtual void SendHealth (void) override; virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) override; - virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player) override; virtual void SendMetadata (const cEntity & a_Entity) override; diff --git a/source/Protocol132.cpp b/source/Protocol132.cpp new file mode 100644 index 000000000..faff57004 --- /dev/null +++ b/source/Protocol132.cpp @@ -0,0 +1,65 @@ + +// Protocol132.cpp + +// Implements the cProtocol132 class representing the release 1.3.2 protocol (#39) + +#include "Globals.h" +#include "Protocol132.h" + + + + + +#define HANDLE_PACKET_READ(Proc, Type, Var) \ + Type Var; \ + { \ + if (!m_ReceivedData.Proc(Var)) \ + { \ + return PARSE_INCOMPLETE; \ + } \ + } + + + + +typedef unsigned char Byte; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cProtocol132: + +cProtocol132::cProtocol132(cClientHandle * a_Client) : + super(a_Client) +{ +} + + + + + +void cProtocol132::DataReceived(const char * a_Data, int a_Size) +{ + // TODO: Protocol decryption + super::DataReceived(a_Data, a_Size); +} + + + + + +int cProtocol132::ParseHandshake(void) +{ + HANDLE_PACKET_READ(ReadByte, Byte, ProtocolVersion); + HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username); + HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ServerHost); + HANDLE_PACKET_READ(ReadBEInt, int, ServerPort); + m_Username = Username; + return PARSE_OK; +} + + + + diff --git a/source/Protocol132.h b/source/Protocol132.h new file mode 100644 index 000000000..af3e78ecc --- /dev/null +++ b/source/Protocol132.h @@ -0,0 +1,35 @@ + +// Protocol132.h + +// Interfaces to the cProtocol132 class representing the release 1.3.2 protocol (#39) + + + + + +#pragma once + +#include "Protocol125.h" + + + + + +class cProtocol132 : + public cProtocol125 +{ + typedef cProtocol125 super; +public: + + cProtocol132(cClientHandle * a_Client); + + /// Called when client sends some data: + virtual void DataReceived(const char * a_Data, int a_Size) override; + + // Modified packets: + virtual int ParseHandshake(void) override; +} ; + + + + diff --git a/source/ProtocolRecognizer.cpp b/source/ProtocolRecognizer.cpp new file mode 100644 index 000000000..af917b7de --- /dev/null +++ b/source/ProtocolRecognizer.cpp @@ -0,0 +1,522 @@ + +// ProtocolRecognizer.cpp + +// Implements the cProtocolRecognizer class representing the meta-protocol that recognizes possibly multiple +// protocol versions and redirects everything to them + +#include "Globals.h" + +#include "ProtocolRecognizer.h" +#include "Protocol125.h" +#include "Protocol132.h" +#include "cClientHandle.h" +#include "cRoot.h" +#include "cWorld.h" +#include "cChatColor.h" + + + + + +cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : + super(a_Client), + m_Protocol(NULL), + m_Buffer(512) +{ +} + + + + + +void cProtocolRecognizer::DataReceived(const char * a_Data, int a_Size) +{ + if (m_Protocol == NULL) + { + if (!m_Buffer.Write(a_Data, a_Size)) + { + m_Client->Kick("Unsupported protocol version"); + return; + } + + if (!TryRecognizeProtocol()) + { + return; + } + LOGD("ProtocolRecognizer at %p recognized protocol %p", this, m_Protocol); + + // The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing: + AString Dump; + m_Buffer.ResetRead(); + m_Buffer.ReadAll(Dump); + m_Protocol->DataReceived(Dump.data(), Dump.size()); + } + else + { + m_Protocol->DataReceived(a_Data, a_Size); + } +} + + + + + +void cProtocolRecognizer::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2); +} + + + + + +void cProtocolRecognizer::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); +} + + + + + +void cProtocolRecognizer::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); +} + + + + + +void cProtocolRecognizer::SendChat(const AString & a_Message) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendChat(a_Message); +} + + + + + +void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer); +} + + + + + +void cProtocolRecognizer::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendCollectPickup(a_Pickup, a_Player); +} + + + + + +void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendDestroyEntity(a_Entity); +} + + + + + +void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) +{ + if (m_Protocol != NULL) + { + m_Protocol->SendDisconnect(a_Reason); + } + else + { + // This is used when the client sends a server-ping, respond with the default packet: + WriteByte ((char)0xff); // PACKET_DISCONNECT + WriteString(a_Reason); + } +} + + + + + +void cProtocolRecognizer::SendEntHeadLook(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntHeadLook(a_Entity); +} + + + + + +void cProtocolRecognizer::SendEntLook(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntLook(a_Entity); +} + + + + + +void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item); +} + + + + + +void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Status) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntityStatus(a_Entity, a_Status); +} + + + + + +void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendGameMode(a_GameMode); +} + + + + + +void cProtocolRecognizer::SendHealth(void) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendHealth(); +} + + + + + +void cProtocolRecognizer::SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendInventoryProgress(a_WindowID, a_Progressbar, a_Value); +} + + + + + +void cProtocolRecognizer::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item); +} + + + + + +void cProtocolRecognizer::SendKeepAlive(int a_PingID) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendKeepAlive(a_PingID); +} + + + + + +void cProtocolRecognizer::SendLogin(const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendLogin(a_Player); +} + + + + + +void cProtocolRecognizer::SendMetadata(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendMetadata(a_Entity); +} + + + + + +void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPickupSpawn(a_Pickup); +} + + + + + +void cProtocolRecognizer::SendPlayerAnimation(const cPlayer & a_Player, char a_Animation) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerAnimation(a_Player, a_Animation); +} + + + + + +void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); +} + + + + + +void cProtocolRecognizer::SendPlayerMoveLook(void) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerMoveLook(); +} + + + + + +void cProtocolRecognizer::SendPlayerPosition(void) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerPosition(); +} + + + + + +void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerSpawn(a_Player); +} + + + + + +void cProtocolRecognizer::SendEntRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntRelMove(a_Entity, a_RelX, a_RelY, a_RelZ); +} + + + + + +void cProtocolRecognizer::SendEntRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ); +} + + + + + +void cProtocolRecognizer::SendRespawn(void) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendRespawn(); +} + + + + + +void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendSpawnMob(a_Mob); +} + + + + + +void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendTeleportEntity(a_Entity); +} + + + + + +void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendThunderbolt(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldTime) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendTimeUpdate(a_WorldTime); +} + + + + + +void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ); +} + + + + + +void cProtocolRecognizer::SendUpdateSign(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) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendUpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4); +} + + + + + +void cProtocolRecognizer::SendWeather(eWeather a_Weather) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendWeather(a_Weather); +} + + + + + +void cProtocolRecognizer::SendWholeInventory(const cInventory & a_Inventory) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendWholeInventory(a_Inventory); +} + + + + + +void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendWholeInventory(a_Window); +} + + + + + +void cProtocolRecognizer::SendWindowClose(char a_WindowID) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendWindowClose(a_WindowID); +} + + + + + +void cProtocolRecognizer::SendWindowOpen(char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendWindowOpen(a_WindowID, a_WindowType, a_WindowTitle, a_NumSlots); +} + + + + + +void cProtocolRecognizer::SendData(const char * a_Data, int a_Size) +{ + // This is used only when handling the server ping + m_Client->SendData(a_Data, a_Size); +} + + + + + +bool cProtocolRecognizer::TryRecognizeProtocol(void) +{ + // The first packet should be a Handshake, 0x02: + unsigned char PacketType; + if (!m_Buffer.ReadByte(PacketType)) + { + return false; + } + switch (PacketType) + { + case 0x02: break; // Handshake, continue recognizing + case 0xfe: HandleServerPing(); return false; + default: return false; + } + + // 1.3.2 starts with 0x02 0x39 + // 1.2.5 starts with 0x02 and name is expected to less than 0x3900 long :) + char ch; + if (!m_Buffer.ReadChar(ch)) + { + return false; + } + if (ch == 0x39) + { + m_Protocol = new cProtocol132(m_Client); + return true; + } + m_Protocol = new cProtocol125(m_Client); + return true; +} + + + + + +void cProtocolRecognizer::HandleServerPing(void) +{ + AString Reply; + Printf(Reply, "%s%s%i%s%i", + cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + ); + m_Client->Kick(Reply.c_str()); +} + + + + diff --git a/source/ProtocolRecognizer.h b/source/ProtocolRecognizer.h index f4704565e..181c016d9 100644 --- a/source/ProtocolRecognizer.h +++ b/source/ProtocolRecognizer.h @@ -11,6 +11,7 @@ #pragma once #include "Protocol.h" +#include "ByteBuffer.h" @@ -19,6 +20,8 @@ class cProtocolRecognizer : public cProtocol { + typedef cProtocol super; + public: cProtocolRecognizer(cClientHandle * a_Client); @@ -38,21 +41,21 @@ public: virtual void SendEntLook (const cEntity & a_Entity) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; virtual void SendGameMode (eGameMode a_GameMode) override; virtual void SendHealth (void) override; virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) override; - virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player) override; - virtual void SendMetadata (const cPawn & a_Entity) override; + virtual void SendMetadata (const cEntity & a_Entity) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAnimation (const cPlayer & a_Player, char a_Animation) override; virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; virtual void SendRespawn (void) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; @@ -65,10 +68,18 @@ public: virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (char a_WindowID) override; virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; - + + virtual void SendData(const char * a_Data, int a_Size) override; + protected: cProtocol * m_Protocol; //< The recognized protocol - cByteBuffer m_Buffer; //< Buffer used until the protocol is recognized + cByteBuffer m_Buffer; //< Buffer for the incoming data until we recognize the protocol + + /// Tries to recognize protocol based on m_Buffer contents; returns true if recognized + bool TryRecognizeProtocol(void); + + /// Called when the recognizer gets a server ping packet; responds with server stats and destroys the client + void HandleServerPing(void); } ; diff --git a/source/cChatColor.cpp b/source/cChatColor.cpp index cad04676e..262130897 100644 --- a/source/cChatColor.cpp +++ b/source/cChatColor.cpp @@ -3,8 +3,8 @@ #include "cChatColor.h" -const std::string cChatColor::Color = "\xc2\xa7"; // or in other words: "§" -const std::string cChatColor::Delimiter = "\xa7"; +const std::string cChatColor::Color = "\xc2\xa7"; // or in other words: "§" in UTF-8 +const std::string cChatColor::Delimiter = "\xc2\xa7"; // or in other words: "§" in UTF-8 const std::string cChatColor::Black = cChatColor::Color + "0"; const std::string cChatColor::Navy = cChatColor::Color + "1"; const std::string cChatColor::Green = cChatColor::Color + "2"; diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 6d217e6af..0877dba2c 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -40,7 +40,7 @@ #include "cAuthenticator.h" #include "MersenneTwister.h" -#include "Protocol125.h" +#include "ProtocolRecognizer.h" @@ -82,7 +82,6 @@ int cClientHandle::s_ClientCount = 0; cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) : m_ViewDistance(a_ViewDistance) - , m_ProtocolVersion(MCS_PROTOCOL_VERSION) , m_Socket(a_Socket) , m_OutgoingData(64 KiB) , m_bDestroyed(false) @@ -96,7 +95,7 @@ cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) , m_LastStreamedChunkZ(0x7fffffff) , m_UniqueID(0) { - m_Protocol = new cProtocol125(this); + m_Protocol = new cProtocolRecognizer(this); s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread m_UniqueID = s_ClientCount; @@ -447,22 +446,6 @@ bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Usernam -void cClientHandle::HandleUnexpectedPacket(int a_PacketType) -{ - LOGWARNING( - "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"", - m_State, - a_PacketType, - m_Socket.GetIPString().c_str(), - m_Username.c_str() - ); - Kick("Hacked client"); // Don't tell them why we don't like them -} - - - - - void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem) { // This is for creative Inventory changes @@ -571,7 +554,7 @@ void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, cha // Check for clickthrough-blocks: int pX = a_BlockX; - unsigned char pY = a_BlockY; + int pY = a_BlockY; int pZ = a_BlockZ; AddDirection(pX, pY, pZ, a_BlockFace); @@ -666,7 +649,7 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c } - int PlaceBlock = m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + BLOCKTYPE PlaceBlock = m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if (!BlockHandler(PlaceBlock)->IgnoreBuildCollision()) { // Tried to place a block *into* another? @@ -776,7 +759,6 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_ double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); if (Dist < 1.0) { - // Test if (ReceivedPosition.Equals(m_ConfirmPosition)) { LOGINFO("Exact position confirmed by client!"); @@ -785,7 +767,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_ } else { - LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist); + LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), sqrt(Dist)); m_ConfirmPosition = m_Player->GetPosition(); SendPlayerMoveLook(); } @@ -998,7 +980,10 @@ void cClientHandle::Tick(float a_Dt) cTimer t1; // Send ping packet - if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) + if ( + (m_Player != NULL) && // Is logged in? + (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) + ) { m_PingID++; m_PingStartTime = t1.GetNowTime(); @@ -1021,7 +1006,7 @@ void cClientHandle::SendDisconnect(const AString & a_Reason) -void cClientHandle::SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item) +void cClientHandle::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item); } diff --git a/source/cClientHandle.h b/source/cClientHandle.h index 8ef670837..0b25365df 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -83,7 +83,7 @@ public: bool IsPlaying(void) const {return (m_State == csPlaying); } void SendDisconnect(const AString & a_Reason); - void SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item); + void SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item); void SendChat(const AString & a_Message); void SendPlayerAnimation(const cPlayer & a_Player, char a_Animation); void SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); @@ -142,8 +142,6 @@ public: // Calls that cProtocol descendants use for handling packets: void HandlePing (void); - - void HandleUnexpectedPacket (int a_PacketType); // the default case -> kick void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem); void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); void HandleBlockDig (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); diff --git a/source/cCraftingWindow.cpp b/source/cCraftingWindow.cpp index 0f03167c8..fee000da3 100644 --- a/source/cCraftingWindow.cpp +++ b/source/cCraftingWindow.cpp @@ -118,7 +118,7 @@ void cCraftingWindow::Clicked( a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); // Separate packet for result =/ Don't know why - a_Player.GetClientHandle()->SendInventorySlot(GetWindowID(), 0, *GetSlot(0)); + a_Player.GetClientHandle()->SendInventorySlot((char)GetWindowID(), 0, *GetSlot(0)); }