diff options
author | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-08-30 11:56:59 +0200 |
---|---|---|
committer | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-08-30 11:56:59 +0200 |
commit | f5fe723b2a704da475b24a594fd59f448cf133a3 (patch) | |
tree | 6965c6df44d2b042ca62034119466127fd01b5da /source | |
parent | cProtocol handles the initial handshake up to player login (diff) | |
download | cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar.gz cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar.bz2 cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar.lz cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar.xz cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.tar.zst cuberite-f5fe723b2a704da475b24a594fd59f448cf133a3.zip |
Diffstat (limited to 'source')
-rw-r--r-- | source/Protocol.h | 2 | ||||
-rw-r--r-- | source/Protocol125.cpp | 6 | ||||
-rw-r--r-- | source/Protocol125.h | 2 | ||||
-rw-r--r-- | source/Protocol132.cpp | 65 | ||||
-rw-r--r-- | source/Protocol132.h | 35 | ||||
-rw-r--r-- | source/ProtocolRecognizer.cpp | 522 | ||||
-rw-r--r-- | source/ProtocolRecognizer.h | 23 | ||||
-rw-r--r-- | source/cChatColor.cpp | 4 | ||||
-rw-r--r-- | source/cClientHandle.cpp | 35 | ||||
-rw-r--r-- | source/cClientHandle.h | 4 | ||||
-rw-r--r-- | source/cCraftingWindow.cpp | 2 |
11 files changed, 658 insertions, 42 deletions
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 <name-length-short>
+ // 1.2.5 starts with 0x02 <name-length-short> 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)); } |