#include "Globals.h" #include "LengthenedProtocol.h" #include "ClientAction.h" cProtocol::cProtocolError cLengthenedProtocol::DataReceived(const char * a_Data, size_t a_Size, std::vector> & a_Actions) { a_Actions.clear(); if (m_IsEncrypted) { ASSERT((a_Size % 16) == 0); // AES requirement. Byte Decrypted[512]; while (a_Size > 0) { size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; m_Decryptor.ProcessData(Decrypted, reinterpret_cast(a_Data), NumBytes); auto success = AddReceivedData(reinterpret_cast(Decrypted), NumBytes, a_Actions); if (success != cProtocolError::Success) { return success; } a_Size -= NumBytes; a_Data += NumBytes; } return cProtocolError::Success; } else { return AddReceivedData(a_Data, a_Size, a_Actions); } } cProtocol::cProtocolError cLengthenedProtocol::AddReceivedData(const char * a_Data, size_t a_Size, std::vector> & a_Actions) { // Write the incoming data into the comm log file: if (g_ShouldLogCommIn) { if (m_ReceivedData.GetReadableSpace() > 0) { AString AllData; size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); m_ReceivedData.ReadAll(AllData); m_ReceivedData.ResetRead(); m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); m_CommLogFile.Printf("Incoming data, " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") unparsed bytes already present in buffer:\n%s\n", AllData.size(), AllData.size(), Hex.c_str() ); } AString Hex; CreateHexDump(Hex, a_Data, a_Size, 16); m_CommLogFile.Printf("Incoming data: %u (0x%x) bytes: \n%s\n", static_cast(a_Size), static_cast(a_Size), Hex.c_str() ); m_CommLogFile.Flush(); } if (!m_ReceivedData.Write(a_Data, a_Size)) { return cProtocolError::BufferFull; } auto status = OnDataAddedToBuffer(m_ReceivedData, a_Actions); if (status != cProtocolError::Success) { return status; } // Log any leftover bytes into the logfile: if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0)) { AString AllData; size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); m_ReceivedData.ReadAll(AllData); m_ReceivedData.ResetRead(); m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); m_CommLogFile.Printf("There are " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") bytes of non-parse-able data left in the buffer:\n%s", m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() ); m_CommLogFile.Flush(); } return cProtocolError::Success; } #define ADD_SIMPLE_ACTION(Name) a_Action.push_back(cpp14::make_unique(cClientAction::Type::Name)); cProtocol::cProtocolError cLengthenedProtocol::HandleHandshake(cByteBuffer & a_ByteBuffer, std::vector> & a_Action) { // these need to replace the values provided to the constructor in the old version if (!a_ByteBuffer.ReadVarUTF8String(m_ServerAddress)) { return cProtocolError::PacketReadError; } if (!a_ByteBuffer.ReadBEUInt16(m_ServerPort)) { return cProtocolError::PacketReadError; } if (!a_ByteBuffer.ReadVarInt(m_State)) { return cProtocolError::PacketReadError; } a_ByteBuffer.CommitRead(); // BungeeCord handling: // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: // hostname\00ip-address\00uuid\00profile-properties-as-json AStringVector Params; if (m_ShouldAllowBungeeCord && SplitZeroTerminatedStrings(m_ServerAddress, Params) && (Params.size() == 4)) { LOGD("Player at %s connected via BungeeCord", Params[1].c_str()); m_ServerAddress = Params[0]; //a_Client->SetIPString(Params[1]); //a_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); //a_Client->SetProperties(Params[3]); ADD_SIMPLE_ACTION(SetIPString); ADD_SIMPLE_ACTION(SetUUID); ADD_SIMPLE_ACTION(SetProperties); } return cProtocolError::Success; }