Next iteration on the 1.3.2 protocol. Still no good, but sometimes it just gets through. For your testing pleasures ;)
git-svn-id: http://mc-server.googlecode.com/svn/trunk@819 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
926903905b
commit
c7d5c00a17
@ -24,6 +24,7 @@ class cPawn;
|
||||
class cPickup;
|
||||
class cMonster;
|
||||
class cChunkDataSerializer;
|
||||
class cWorld;
|
||||
|
||||
|
||||
|
||||
@ -60,7 +61,7 @@ public:
|
||||
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) = 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 SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0;
|
||||
virtual void SendMetadata (const cEntity & a_Entity) = 0;
|
||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0;
|
||||
virtual void SendPlayerAnimation (const cPlayer & a_Player, char a_Animation) = 0;
|
||||
|
@ -417,8 +417,9 @@ void cProtocol125::SendKeepAlive(int a_PingID)
|
||||
|
||||
|
||||
|
||||
void cProtocol125::SendLogin(const cPlayer & a_Player)
|
||||
void cProtocol125::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
||||
{
|
||||
UNUSED(a_World);
|
||||
cCSLock Lock(m_CSPacket);
|
||||
|
||||
WriteByte (PACKET_LOGIN);
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) 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 SendLogin (const cPlayer & a_Player, const cWorld & a_World) 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;
|
||||
|
@ -52,11 +52,12 @@ enum
|
||||
{
|
||||
PACKET_KEEP_ALIVE = 0x00,
|
||||
PACKET_LOGIN = 0x01,
|
||||
PACKET_COMPASS = 0x06,
|
||||
PACKET_PLAYER_SPAWN = 0x14,
|
||||
PACKET_SPAWN_MOB = 0x18,
|
||||
PACKET_DESTROY_ENTITIES = 0x1d,
|
||||
PACKET_CHUNK_DATA = 0x33,
|
||||
PACKET_BLOCK_CHANGE = 0x34,
|
||||
PACKET_BLOCK_CHANGE = 0x35,
|
||||
PACKET_BLOCK_ACTION = 0x36,
|
||||
} ;
|
||||
|
||||
@ -156,11 +157,11 @@ void cProtocol132::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO
|
||||
|
||||
void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||
{
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
|
||||
// Pre-chunk not used in 1.3.2. Finally.
|
||||
|
||||
//*
|
||||
// Send the chunk data:
|
||||
// Chunk data seems to break the connection for some reason; without it, the connection lives indefinitely
|
||||
AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2);
|
||||
@ -169,7 +170,9 @@ void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
|
||||
WriteInt (a_ChunkZ);
|
||||
SendData(Serialized.data(), Serialized.size());
|
||||
Flush();
|
||||
//*/
|
||||
}
|
||||
// Enabling the sleep here sometimes makes the client accept us and spawn us in the world. But it makes the connection lag behind, ultimately timing out
|
||||
// cSleep::MilliSleep(500);
|
||||
}
|
||||
|
||||
|
||||
@ -201,7 +204,7 @@ void cProtocol132::SendKeepAlive(int a_PingID)
|
||||
|
||||
|
||||
|
||||
void cProtocol132::SendLogin(const cPlayer & a_Player)
|
||||
void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte (PACKET_LOGIN);
|
||||
@ -213,6 +216,8 @@ void cProtocol132::SendLogin(const cPlayer & a_Player)
|
||||
WriteByte (0); // Unused, used to be world height
|
||||
WriteByte (8); // Client list width or something
|
||||
Flush();
|
||||
|
||||
SendCompass(a_World);
|
||||
}
|
||||
|
||||
|
||||
@ -278,7 +283,7 @@ void cProtocol132::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
int cProtocol132::ParsePacket(unsigned char a_PacketType)
|
||||
{
|
||||
// DEBUG:
|
||||
LOGD("Received packet 0x%02x, current bytecount %d, enc %d", a_PacketType, m_CurrentIn, m_EncIn);
|
||||
LOGD("Received packet 0x%02x, %d B avail; BM %d, enc %d", a_PacketType, m_ReceivedData.GetReadableSpace(), m_CurrentIn, m_EncIn);
|
||||
|
||||
switch (a_PacketType)
|
||||
{
|
||||
@ -327,18 +332,12 @@ int cProtocol132::ParseHandshake(void)
|
||||
HANDLE_PACKET_READ(ReadBEInt, int, ServerPort);
|
||||
m_Username = Username;
|
||||
|
||||
// Send a 0xFD Encryption Key Request http://wiki.vg/Protocol#0xFD
|
||||
AString key;
|
||||
CryptoPP::StringSink sink(key); // GCC won't allow inline instantiation in the following line, damned temporary refs
|
||||
cRoot::Get()->GetServer()->GetPublicKey().Save(sink);
|
||||
|
||||
// Send a 0xFD Encryption Key Request http://wiki.vg/Protocol#0xFD
|
||||
WriteByte((char)0xfd);
|
||||
WriteString("MCServer");
|
||||
WriteShort((short)key.size());
|
||||
SendData(key.data(), key.size());
|
||||
WriteShort(4);
|
||||
WriteInt((int)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
|
||||
Flush();
|
||||
SendEncryptionKeyRequest(key);
|
||||
|
||||
return PARSE_OK;
|
||||
}
|
||||
|
||||
@ -440,22 +439,30 @@ void cProtocol132::SendData(const char * a_Data, int a_Size)
|
||||
void cProtocol132::Flush(void)
|
||||
{
|
||||
// DEBUG
|
||||
ASSERT(m_CSPacket.IsLockedByCurrentThread()); // Did all packets lock the CS properly?
|
||||
|
||||
if (m_DataToSend.empty())
|
||||
{
|
||||
LOGD("Flushing empty");
|
||||
return;
|
||||
}
|
||||
LOGD("Flushing packet 0x%02x, %d bytes; %d bytes out, %d enc out", (unsigned char)m_DataToSend[0], m_DataToSend.size(), m_CurrentOut, m_EncOut);
|
||||
LOGD("Flushing packet 0x%02x, %d B; %d B out, %d enc out", (unsigned char)m_DataToSend[0], m_DataToSend.size(), m_CurrentOut, m_EncOut);
|
||||
const char * a_Data = m_DataToSend.data();
|
||||
int a_Size = m_DataToSend.size();
|
||||
if (m_IsEncrypted)
|
||||
{
|
||||
m_EncOut += a_Size;
|
||||
byte Encrypted[4096]; // Larger buffer, we may be sending lots of data (chunks)
|
||||
byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks)
|
||||
while (a_Size > 0)
|
||||
{
|
||||
int NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size;
|
||||
m_Encryptor.ProcessData(Encrypted, (byte *)a_Data, NumBytes);
|
||||
|
||||
// DEBUG: decrypt the data to check if encryption works:
|
||||
byte Decrypted[sizeof(Encrypted)];
|
||||
m_Decryptor2.ProcessData(Decrypted, Encrypted, NumBytes);
|
||||
ASSERT(memcmp(Decrypted, a_Data, NumBytes) == 0);
|
||||
|
||||
super::SendData((const char *)Encrypted, NumBytes);
|
||||
a_Size -= NumBytes;
|
||||
a_Data += NumBytes;
|
||||
@ -466,7 +473,7 @@ void cProtocol132::Flush(void)
|
||||
super::SendData(a_Data, a_Size);
|
||||
}
|
||||
m_DataToSend.clear();
|
||||
// cSleep::MilliSleep(300);
|
||||
// cSleep::MilliSleep(400);
|
||||
}
|
||||
|
||||
|
||||
@ -500,6 +507,75 @@ void cProtocol132::WriteItem(const cItem & a_Item)
|
||||
|
||||
|
||||
|
||||
int cProtocol132::ParseItem(cItem & a_Item)
|
||||
{
|
||||
HANDLE_PACKET_READ(ReadBEShort, short, ItemType);
|
||||
|
||||
if (ItemType <= -1)
|
||||
{
|
||||
a_Item.Empty();
|
||||
return PARSE_OK;
|
||||
}
|
||||
a_Item.m_ItemType = ItemType;
|
||||
|
||||
HANDLE_PACKET_READ(ReadChar, char, ItemCount);
|
||||
HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage);
|
||||
a_Item.m_ItemCount = ItemCount;
|
||||
// a_Item.m_ItemDamage = ItemDamage;
|
||||
if (ItemCount <= 0)
|
||||
{
|
||||
a_Item.Empty();
|
||||
}
|
||||
|
||||
HANDLE_PACKET_READ(ReadBEShort, short, EnchantNumBytes);
|
||||
if (EnchantNumBytes <= 0)
|
||||
{
|
||||
return PARSE_OK;
|
||||
}
|
||||
|
||||
// TODO: Enchantment not implemented yet!
|
||||
if (!m_ReceivedData.SkipRead(EnchantNumBytes))
|
||||
{
|
||||
return PARSE_INCOMPLETE;
|
||||
}
|
||||
|
||||
return PARSE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol132::SendCompass(const cWorld & a_World)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte(PACKET_COMPASS);
|
||||
WriteInt((int)(a_World.GetSpawnX()));
|
||||
WriteInt((int)(a_World.GetSpawnY()));
|
||||
WriteInt((int)(a_World.GetSpawnZ()));
|
||||
Flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol132::SendEncryptionKeyRequest(const AString & a_Key)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte((char)0xfd);
|
||||
WriteString("MCServer");
|
||||
WriteShort((short)a_Key.size());
|
||||
SendData(a_Key.data(), a_Key.size());
|
||||
WriteShort(4);
|
||||
WriteInt((int)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
|
||||
Flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce)
|
||||
{
|
||||
// Decrypt EncNonce using privkey
|
||||
@ -530,11 +606,14 @@ void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const A
|
||||
return;
|
||||
}
|
||||
|
||||
// Send encryption key response:
|
||||
WriteByte((char)0xfc);
|
||||
WriteShort(0);
|
||||
WriteShort(0);
|
||||
Flush();
|
||||
{
|
||||
// Send encryption key response:
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte((char)0xfc);
|
||||
WriteShort(0);
|
||||
WriteShort(0);
|
||||
Flush();
|
||||
}
|
||||
|
||||
StartEncryption(DecryptedKey);
|
||||
return;
|
||||
@ -548,6 +627,7 @@ void cProtocol132::StartEncryption(const byte * a_Key)
|
||||
{
|
||||
m_Encryptor.SetKey(a_Key, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(a_Key, 16))(Name::FeedbackSize(), 1));
|
||||
m_Decryptor.SetKey(a_Key, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(a_Key, 16))(Name::FeedbackSize(), 1));
|
||||
m_Decryptor2.SetKey(a_Key, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(a_Key, 16))(Name::FeedbackSize(), 1));
|
||||
m_IsEncrypted = true;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendDestroyEntity(const cEntity & a_Entity) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
|
||||
@ -64,6 +64,7 @@ protected:
|
||||
CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption m_Encryptor;
|
||||
|
||||
// DEBUG:
|
||||
CryptoPP::CFB_Mode<CryptoPP::AES>::Decryption m_Decryptor2;
|
||||
AString m_DataToSend;
|
||||
int m_CurrentIn, m_CurrentOut;
|
||||
int m_EncIn, m_EncOut;
|
||||
@ -75,6 +76,10 @@ protected:
|
||||
|
||||
// Items in slots are sent differently
|
||||
virtual void WriteItem(const cItem & a_Item) override;
|
||||
virtual int ParseItem(cItem & a_Item) override;
|
||||
|
||||
virtual void SendCompass(const cWorld & a_World);
|
||||
virtual void SendEncryptionKeyRequest(const AString & a_Key);
|
||||
|
||||
/// Decrypts the key and nonce, checks nonce, starts the symmetric encryption
|
||||
void HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce);
|
||||
|
@ -238,10 +238,10 @@ void cProtocolRecognizer::SendKeepAlive(int a_PingID)
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendLogin(const cPlayer & a_Player)
|
||||
void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
||||
{
|
||||
ASSERT(m_Protocol != NULL);
|
||||
m_Protocol->SendLogin(a_Player);
|
||||
m_Protocol->SendLogin(a_Player, a_World);
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) 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 SendLogin (const cPlayer & a_Player, const cWorld & a_World) 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;
|
||||
|
@ -244,7 +244,7 @@ void cClientHandle::Authenticate(void)
|
||||
cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_PLAYER_SPAWN, 1, m_Player);
|
||||
|
||||
// Return a server login packet
|
||||
m_Protocol->SendLogin(*m_Player);
|
||||
m_Protocol->SendLogin(*m_Player, *World);
|
||||
|
||||
// Send Weather if raining:
|
||||
if ((World->GetWeather() == 1) || (World->GetWeather() == 2))
|
||||
|
@ -1205,15 +1205,6 @@ int cWorld::GetHeight( int a_X, int a_Z )
|
||||
|
||||
|
||||
|
||||
const double & cWorld::GetSpawnY(void)
|
||||
{
|
||||
return m_SpawnY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
|
@ -263,9 +263,9 @@ public:
|
||||
bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export
|
||||
void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export
|
||||
|
||||
const double & GetSpawnX() { return m_SpawnX; } //tolua_export
|
||||
const double & GetSpawnY(); //tolua_export
|
||||
const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export
|
||||
const double & GetSpawnX(void) const { return m_SpawnX; } // tolua_export
|
||||
const double & GetSpawnY(void) const { return m_SpawnY; } // tolua_export
|
||||
const double & GetSpawnZ(void) const { return m_SpawnZ; } // tolua_export
|
||||
|
||||
inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; }
|
||||
inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; }
|
||||
|
Loading…
Reference in New Issue
Block a user